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