arnaucube
arnaucube/comunicationLeapPublic Self-hosted repository
comunicationLeap/node_modules/socket.io/lib/namespace.js
node_modules/socket.io/lib/namespace.jsRaw
  1
  2/**
  3 * Module dependencies.
  4 */
  5
  6var Socket = require('./socket');
  7var Emitter = require('events').EventEmitter;
  8var parser = require('socket.io-parser');
  9var debug = require('debug')('socket.io:namespace');
 10var hasBin = require('has-binary-data');
 11
 12/**
 13 * Module exports.
 14 */
 15
 16module.exports = exports = Namespace;
 17
 18/**
 19 * Blacklisted events.
 20 */
 21
 22exports.events = [
 23  'connect',    // for symmetry with client
 24  'connection',
 25  'newListener'
 26];
 27
 28/**
 29 * Flags.
 30 */
 31
 32exports.flags = ['json'];
 33
 34/**
 35 * `EventEmitter#emit` reference.
 36 */
 37
 38var emit = Emitter.prototype.emit;
 39
 40/**
 41 * Namespace constructor.
 42 *
 43 * @param {Server} server instance
 44 * @param {Socket} name
 45 * @api private
 46 */
 47
 48function Namespace(server, name){
 49  this.name = name;
 50  this.server = server;
 51  this.sockets = [];
 52  this.connected = {};
 53  this.fns = [];
 54  this.ids = 0;
 55  this.acks = {};
 56  this.initAdapter();
 57}
 58
 59/**
 60 * Inherits from `EventEmitter`.
 61 */
 62
 63Namespace.prototype.__proto__ = Emitter.prototype;
 64
 65/**
 66 * Apply flags from `Socket`.
 67 */
 68
 69exports.flags.forEach(function(flag){
 70  Namespace.prototype.__defineGetter__(flag, function(){
 71    this.flags = this.flags || {};
 72    this.flags[flag] = true;
 73    return this;
 74  });
 75});
 76
 77/**
 78 * Initializes the `Adapter` for this nsp.
 79 * Run upon changing adapter by `Server#adapter`
 80 * in addition to the constructor.
 81 *
 82 * @api private
 83 */
 84
 85Namespace.prototype.initAdapter = function(){
 86  this.adapter = new (this.server.adapter())(this);
 87};
 88
 89/**
 90 * Sets up namespace middleware.
 91 *
 92 * @return {Namespace} self
 93 * @api public
 94 */
 95
 96Namespace.prototype.use = function(fn){
 97  this.fns.push(fn);
 98  return this;
 99};
100
101/**
102 * Executes the middleware for an incoming client.
103 *
104 * @param {Socket} socket that will get added
105 * @param {Function} last fn call in the middleware
106 * @api private
107 */
108
109Namespace.prototype.run = function(socket, fn){
110  var fns = this.fns.slice(0);
111  if (!fns.length) return fn(null);
112
113  function run(i){
114    fns[i](socket, function(err){
115      // upon error, short-circuit
116      if (err) return fn(err);
117
118      // if no middleware left, summon callback
119      if (!fns[i + 1]) return fn(null);
120
121      // go on to next
122      run(i + 1);
123    });
124  }
125
126  run(0);
127};
128
129/**
130 * Targets a room when emitting.
131 *
132 * @param {String} name
133 * @return {Namespace} self
134 * @api public
135 */
136
137Namespace.prototype.to =
138Namespace.prototype['in'] = function(name){
139  this.rooms = this.rooms || [];
140  if (!~this.rooms.indexOf(name)) this.rooms.push(name);
141  return this;
142};
143
144/**
145 * Adds a new client.
146 *
147 * @return {Socket}
148 * @api private
149 */
150
151Namespace.prototype.add = function(client, fn){
152  debug('adding socket to nsp %s', this.name);
153  var socket = new Socket(this, client);
154  var self = this;
155  this.run(socket, function(err){
156    process.nextTick(function(){
157      if ('open' == client.conn.readyState) {
158        if (err) return socket.error(err.data || err.message);
159
160        // track socket
161        self.sockets.push(socket);
162
163        // it's paramount that the internal `onconnect` logic
164        // fires before user-set events to prevent state order
165        // violations (such as a disconnection before the connection
166        // logic is complete)
167        socket.onconnect();
168        if (fn) fn();
169
170        // fire user-set events
171        self.emit('connect', socket);
172        self.emit('connection', socket);
173      } else {
174        debug('next called after client was closed - ignoring socket');
175      }
176    });
177  });
178  return socket;
179};
180
181/**
182 * Removes a client. Called by each `Socket`.
183 *
184 * @api private
185 */
186
187Namespace.prototype.remove = function(socket){
188  var i = this.sockets.indexOf(socket);
189  if (~i) {
190    this.sockets.splice(i, 1);
191  } else {
192    debug('ignoring remove for %s', socket.id);
193  }
194};
195
196/**
197 * Emits to all clients.
198 *
199 * @return {Namespace} self
200 * @api public
201 */
202
203Namespace.prototype.emit = function(ev){
204  if (~exports.events.indexOf(ev)) {
205    emit.apply(this, arguments);
206  } else {
207    // set up packet object
208    var args = Array.prototype.slice.call(arguments);
209    var parserType = parser.EVENT; // default
210    if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary
211
212    var packet = { type: parserType, data: args };
213
214    if ('function' == typeof args[args.length - 1]) {
215      throw new Error('Callbacks are not supported when broadcasting');
216    }
217
218    this.adapter.broadcast(packet, {
219      rooms: this.rooms,
220      flags: this.flags
221    });
222
223    delete this.rooms;
224    delete this.flags;
225  }
226  return this;
227};
228
229/**
230 * Sends a `message` event to all clients.
231 *
232 * @return {Namespace} self
233 * @api public
234 */
235
236Namespace.prototype.send =
237Namespace.prototype.write = function(){
238  var args = Array.prototype.slice.call(arguments);
239  args.unshift('message');
240  this.emit.apply(this, args);
241  return this;
242};