| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 | 
							- /**
 
-  * @file Represents a websocket server
 
-  */
 
- 'use strict'
 
- function nop() {}
 
- var util = require('util'),
 
- 	net = require('net'),
 
- 	tls = require('tls'),
 
- 	events = require('events'),
 
- 	Connection
 
- /**
 
-  * @callback SelectProtocolCallback
 
-  * @param {Connection} connection
 
-  * @param {Array<string>} protocols
 
-  * @returns {?string}
 
-  */
 
- /**
 
-  * Creates a new ws server and starts listening for new connections
 
-  * @class
 
-  * @param {boolean} secure indicates if it should use tls
 
-  * @param {Object} [options] will be passed to net.createServer() or tls.createServer()
 
-  * @param {Array<string>} [options.validProtocols]
 
-  * @param {SelectProtocolCallback} [options.selectProtocol]
 
-  * @param {Function} [callback] will be added as "connection" listener
 
-  * @inherits EventEmitter
 
-  * @event listening
 
-  * @event close
 
-  * @event error an error object is passed
 
-  * @event connection a Connection object is passed
 
-  */
 
- function Server(secure, options, callback) {
 
- 	var that = this
 
- 	if (typeof options === 'function') {
 
- 		callback = options
 
- 		options = undefined
 
- 	}
 
- 	var onConnection = function (socket) {
 
- 		var conn = new Connection(socket, that, function () {
 
- 			that.connections.push(conn)
 
- 			conn.removeListener('error', nop)
 
- 			that.emit('connection', conn)
 
- 		})
 
- 		conn.on('close', function () {
 
- 			var pos = that.connections.indexOf(conn)
 
- 			if (pos !== -1) {
 
- 				that.connections.splice(pos, 1)
 
- 			}
 
- 		})
 
- 		// Ignore errors before the connection is established
 
- 		conn.on('error', nop)
 
- 	}
 
- 	if (secure) {
 
- 		this.socket = tls.createServer(options, onConnection)
 
- 	} else {
 
- 		this.socket = net.createServer(options, onConnection)
 
- 	}
 
- 	this.socket.on('close', function () {
 
- 		that.emit('close')
 
- 	})
 
- 	this.socket.on('error', function (err) {
 
- 		that.emit('error', err)
 
- 	})
 
- 	this.connections = []
 
- 	// super constructor
 
- 	events.EventEmitter.call(this)
 
- 	if (callback) {
 
- 		this.on('connection', callback)
 
- 	}
 
- 	// Add protocol agreement handling
 
- 	/**
 
- 	 * @member {?SelectProtocolCallback}
 
- 	 * @private
 
- 	 */
 
- 	this._selectProtocol = null
 
- 	if (options && options.selectProtocol) {
 
- 		// User-provided logic
 
- 		this._selectProtocol = options.selectProtocol
 
- 	} else if (options && options.validProtocols) {
 
- 		// Default logic
 
- 		this._selectProtocol = this._buildSelectProtocol(options.validProtocols)
 
- 	}
 
- }
 
- util.inherits(Server, events.EventEmitter)
 
- module.exports = Server
 
- Connection = require('./Connection')
 
- /**
 
-  * Start listening for connections
 
-  * @param {number} port
 
-  * @param {string} [host]
 
-  * @param {Function} [callback] will be added as "connection" listener
 
-  */
 
- Server.prototype.listen = function (port, host, callback) {
 
- 	var that = this
 
- 	if (typeof host === 'function') {
 
- 		callback = host
 
- 		host = undefined
 
- 	}
 
- 	if (callback) {
 
- 		this.on('listening', callback)
 
- 	}
 
- 	this.socket.listen(port, host, function () {
 
- 		that.emit('listening')
 
- 	})
 
- 	return this
 
- }
 
- /**
 
-  * Stops the server from accepting new connections and keeps existing connections.
 
-  * This function is asynchronous, the server is finally closed when all connections are ended and the server emits a 'close' event.
 
-  * The optional callback will be called once the 'close' event occurs.
 
-  * @param {function()} [callback]
 
-  */
 
- Server.prototype.close = function (callback) {
 
- 	if (callback) {
 
- 		this.once('close', callback)
 
- 	}
 
- 	this.socket.close()
 
- }
 
- /**
 
-  * Create a resolver to pick the client's most preferred protocol the server recognises
 
-  * @param {Array<string>} validProtocols
 
-  * @returns {SelectProtocolCallback}
 
-  * @private
 
-  */
 
- Server.prototype._buildSelectProtocol = function (validProtocols) {
 
- 	return function (conn, protocols) {
 
- 		var i
 
- 		for (i = 0; i < protocols.length; i++) {
 
- 			if (validProtocols.indexOf(protocols[i]) !== -1) {
 
- 				// A valid protocol was found
 
- 				return protocols[i]
 
- 			}
 
- 		}
 
- 		// No agreement
 
- 	}
 
- }
 
 
  |