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

Paste-bin is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.