var extend = require('./utils').extend; var util = require('util'); var EventEmitter = require('events').EventEmitter; var WebSocketRequest = require('./WebSocketRequest'); var Constants = require('./Constants'); var WebSocketServer = function WebSocketServer(config){ this._handlers = { upgrade: this.handleUpgrade.bind(this), requestAccepted: this.handleRequestAccepted.bind(this)} ; this.connections = [] ; if (config) { this.mount(config); } } ; util.inherits(WebSocketServer, EventEmitter); WebSocketServer.prototype.mount = function (config){ this.config = { httpServer: null , maxReceivedFrameSize: 65536, maxReceivedMessageSize: 1048576, fragmentOutgoingMessages: true , fragmentationThreshold: 16384, keepalive: true , keepaliveInterval: 20000, dropConnectionOnKeepaliveTimeout: true , keepaliveGracePeriod: 10000, useNativeKeepalive: false , assembleFragments: true , autoAcceptConnections: false , disableNagleAlgorithm: true , closeTimeout: 5000} ; extend(this.config, config); if (this.config.httpServer) { this.config.httpServer.on('upgrade', this._handlers.upgrade); } else { throw new Error("You must specify an httpServer on which to mount the WebSocket server.") } } ; WebSocketServer.prototype.unmount = function (){ this.config.httpServer.removeListener('upgrade', this._handlers.upgrade); } ; WebSocketServer.prototype.closeAllConnections = function (){ this.connections.forEach(function (connection){ connection.close(); } ); } ; WebSocketServer.prototype.broadcast = function (data){ if (Buffer.isBuffer(data)) { this.broadcastBytes(data); } else if (typeof (data.toString) === 'function') { this.broadcastUTF(data); } } ; WebSocketServer.prototype.broadcastUTF = function (utfData){ this.connections.forEach(function (connection){ connection.sendUTF(utfData); } ); } ; WebSocketServer.prototype.broadcastBytes = function (binaryData){ this.connections.forEach(function (connection){ connection.sendBytes(binaryData); } ); } ; WebSocketServer.prototype.shutDown = function (){ this.unmount(); this.closeAllConnections(); } ; WebSocketServer.prototype.handleUpgrade = function (request, socket, head){ var wsRequest = new WebSocketRequest(socket, request, this.config); try { wsRequest.readHandshake(); } catch (e) { wsRequest.reject(e.httpCode? e.httpCode: 400, e.message, e.headers); if (Constants.DEBUG) { console.error((new Date()) + " WebSocket: Invalid handshake: " + e.message); } return ; } wsRequest.once('requestAccepted', this._handlers.requestAccepted); if (!this.config.autoAcceptConnections && _AN_Read_length('length', this.listeners('request')) > 0) { this.emit('request', wsRequest); } else if (this.config.autoAcceptConnections) { wsRequest.accept(wsRequest.requestedProtocols[0], wsRequest.origin); } else { wsRequest.reject(404, "No handler is configured to accept the connection."); } } ; WebSocketServer.prototype.handleRequestAccepted = function (connection){ var self = this; connection.once('close', function (closeReason, description){ self.handleConnectionClose(connection, closeReason, description); } ); this.connections.push(connection); this.emit('connect', connection); } ; WebSocketServer.prototype.handleConnectionClose = function (connection, closeReason, description){ var index = this.connections.indexOf(connection); if (index !== -1) { this.connections.splice(index, 1); } this.emit('close', connection, closeReason, description); } ; module.exports = WebSocketServer;