arnaucube
arnaucube/socketioMEANseedPublic Self-hosted repository
socketioMEANseed/server/node_modules/socket.io-adapter/index.js
server/node_modules/socket.io-adapter/index.jsRaw
  1
  2/**
  3 * Module dependencies.
  4 */
  5
  6var Emitter = require('events').EventEmitter;
  7var parser = require('socket.io-parser');
  8
  9/**
 10 * Module exports.
 11 */
 12
 13module.exports = Adapter;
 14
 15/**
 16 * Memory adapter constructor.
 17 *
 18 * @param {Namespace} nsp
 19 * @api public
 20 */
 21
 22function Adapter(nsp){
 23  this.nsp = nsp;
 24  this.rooms = {};
 25  this.sids = {};
 26  this.encoder = new parser.Encoder();
 27}
 28
 29/**
 30 * Inherits from `EventEmitter`.
 31 */
 32
 33Adapter.prototype.__proto__ = Emitter.prototype;
 34
 35/**
 36 * Adds a socket to a room.
 37 *
 38 * @param {String} socket id
 39 * @param {String} room name
 40 * @param {Function} callback
 41 * @api public
 42 */
 43
 44Adapter.prototype.add = function(id, room, fn){
 45  this.sids[id] = this.sids[id] || {};
 46  this.sids[id][room] = true;
 47  this.rooms[room] = this.rooms[room] || Room();
 48  this.rooms[room].add(id);
 49  if (fn) process.nextTick(fn.bind(null, null));
 50};
 51
 52/**
 53 * Removes a socket from a room.
 54 *
 55 * @param {String} socket id
 56 * @param {String} room name
 57 * @param {Function} callback
 58 * @api public
 59 */
 60
 61Adapter.prototype.del = function(id, room, fn){
 62  this.sids[id] = this.sids[id] || {};
 63  delete this.sids[id][room];
 64  if (this.rooms.hasOwnProperty(room)) {
 65    this.rooms[room].del(id);
 66    if (this.rooms[room].length === 0) delete this.rooms[room];
 67  }
 68
 69  if (fn) process.nextTick(fn.bind(null, null));
 70};
 71
 72/**
 73 * Removes a socket from all rooms it's joined.
 74 *
 75 * @param {String} socket id
 76 * @param {Function} callback
 77 * @api public
 78 */
 79
 80Adapter.prototype.delAll = function(id, fn){
 81  var rooms = this.sids[id];
 82  if (rooms) {
 83    for (var room in rooms) {
 84      if (this.rooms.hasOwnProperty(room)) {
 85        this.rooms[room].del(id);
 86        if (this.rooms[room].length === 0) delete this.rooms[room];
 87      }
 88    }
 89  }
 90  delete this.sids[id];
 91
 92  if (fn) process.nextTick(fn.bind(null, null));
 93};
 94
 95/**
 96 * Broadcasts a packet.
 97 *
 98 * Options:
 99 *  - `flags` {Object} flags for this packet
100 *  - `except` {Array} sids that should be excluded
101 *  - `rooms` {Array} list of rooms to broadcast to
102 *
103 * @param {Object} packet object
104 * @api public
105 */
106
107Adapter.prototype.broadcast = function(packet, opts){
108  var rooms = opts.rooms || [];
109  var except = opts.except || [];
110  var flags = opts.flags || {};
111  var packetOpts = {
112    preEncoded: true,
113    volatile: flags.volatile,
114    compress: flags.compress
115  };
116  var ids = {};
117  var self = this;
118  var socket;
119
120  packet.nsp = this.nsp.name;
121  this.encoder.encode(packet, function(encodedPackets) {
122    if (rooms.length) {
123      for (var i = 0; i < rooms.length; i++) {
124        var room = self.rooms[rooms[i]];
125        if (!room) continue;
126        var sockets = room.sockets;
127        for (var id in sockets) {
128          if (sockets.hasOwnProperty(id)) {
129            if (ids[id] || ~except.indexOf(id)) continue;
130            socket = self.nsp.connected[id];
131            if (socket) {
132              socket.packet(encodedPackets, packetOpts);
133              ids[id] = true;
134            }
135          }
136        }
137      }
138    } else {
139      for (var id in self.sids) {
140        if (self.sids.hasOwnProperty(id)) {
141          if (~except.indexOf(id)) continue;
142          socket = self.nsp.connected[id];
143          if (socket) socket.packet(encodedPackets, packetOpts);
144        }
145      }
146    }
147  });
148};
149
150/**
151 * Gets a list of clients by sid.
152 *
153 * @param {Array} explicit set of rooms to check.
154 * @param {Function} callback
155 * @api public
156 */
157
158Adapter.prototype.clients = function(rooms, fn){
159  if ('function' == typeof rooms){
160    fn = rooms;
161    rooms = null;
162  }
163
164  rooms = rooms || [];
165
166  var ids = {};
167  var self = this;
168  var sids = [];
169  var socket;
170
171  if (rooms.length) {
172    for (var i = 0; i < rooms.length; i++) {
173      var room = self.rooms[rooms[i]];
174      if (!room) continue;
175      var sockets = room.sockets;
176      for (var id in sockets) {
177        if (sockets.hasOwnProperty(id)) {
178          if (ids[id]) continue;
179          socket = self.nsp.connected[id];
180          if (socket) {
181            sids.push(id);
182            ids[id] = true;
183          }
184        }
185      }
186    }
187  } else {
188    for (var id in self.sids) {
189      if (self.sids.hasOwnProperty(id)) {
190        socket = self.nsp.connected[id];
191        if (socket) sids.push(id);
192      }
193    }
194  }
195
196  if (fn) process.nextTick(fn.bind(null, null, sids));
197};
198
199/**
200 * Gets the list of rooms a given client has joined.
201 *
202 * @param {String} socket id
203 * @param {Function} callback
204 * @api public
205 */
206Adapter.prototype.clientRooms = function(id, fn){
207  var rooms = this.sids[id];
208  if (fn) process.nextTick(fn.bind(null, null, rooms ? Object.keys(rooms) : null));
209};
210
211/**
212* Room constructor.
213*
214* @api private
215*/
216
217function Room(){
218  if (!(this instanceof Room)) return new Room();
219  this.sockets = {};
220  this.length = 0;
221}
222
223/**
224 * Adds a socket to a room.
225 *
226 * @param {String} socket id
227 * @api private
228 */
229
230Room.prototype.add = function(id){
231  if (!this.sockets.hasOwnProperty(id)) {
232    this.sockets[id] = true;
233    this.length++;
234  }
235};
236
237/**
238 * Removes a socket from a room.
239 *
240 * @param {String} socket id
241 * @api private
242 */
243
244Room.prototype.del = function(id){
245  if (this.sockets.hasOwnProperty(id)) {
246    delete this.sockets[id];
247    this.length--;
248  }
249};