5 var Socket
= require('./socket')
6 , EventEmitter
= process
.EventEmitter
7 , parser
= require('./parser')
8 , util
= require('./util');
11 * Exports the constructor.
14 exports
= module
.exports
= SocketNamespace
;
22 function SocketNamespace (mgr
, name
) {
24 this.name
= name
|| '';
31 * Inherits from EventEmitter.
34 SocketNamespace
.prototype.__proto__
= EventEmitter
.prototype;
37 * Copies emit since we override it
42 SocketNamespace
.prototype.$emit
= EventEmitter
.prototype.emit
;
45 * Retrieves all clients as Socket instances as an array.
50 SocketNamespace
.prototype.clients = function (room
) {
51 var room
= this.name
+ (room
!== undefined ?
54 if (!this.manager
.rooms
[room
]) {
58 return this.manager
.rooms
[room
].map(function (id
) {
59 return this.socket(id
);
64 * Access logger interface.
69 SocketNamespace
.prototype.__defineGetter__('log', function () {
70 return this.manager
.log
;
79 SocketNamespace
.prototype.__defineGetter__('store', function () {
80 return this.manager
.store
;
89 SocketNamespace
.prototype.__defineGetter__('json', function () {
90 this.flags
.json
= true;
95 * Volatile message flag.
100 SocketNamespace
.prototype.__defineGetter__('volatile', function () {
101 this.flags
.volatile
= true;
106 * Overrides the room to relay messages to (flag)
111 SocketNamespace
.prototype.in = function (room
) {
112 this.flags
.endpoint
= this.name
+ (room
? '/' + room
: '');
117 * Adds a session id we should prevent relaying messages to (flag)
122 SocketNamespace
.prototype.except = function (id
) {
123 this.flags
.exceptions
.push(id
);
128 * Sets the default flags.
133 SocketNamespace
.prototype.setFlags = function () {
147 SocketNamespace
.prototype.packet = function (packet
) {
148 packet
.endpoint
= this.name
;
150 var store
= this.store
152 , volatile
= this.flags
.volatile
153 , exceptions
= this.flags
.exceptions
154 , packet
= parser
.encodePacket(packet
);
156 this.manager
.onDispatch(this.flags
.endpoint
, packet
, volatile
, exceptions
);
157 this.store
.publish('dispatch', this.flags
.endpoint
, packet
, volatile
, exceptions
);
170 SocketNamespace
.prototype.send = function (data
) {
172 type
: this.flags
.json
? 'json' : 'message'
178 * Emits to everyone (override)
183 SocketNamespace
.prototype.emit = function (name
) {
184 if (name
== 'newListener') {
185 return this.$emit
.apply(this, arguments
);
191 , args
: util
.toArray(arguments
).slice(1)
196 * Retrieves or creates a write-only socket for a client, unless specified.
198 * @param {Boolean} whether the socket will be readable when initialized
202 SocketNamespace
.prototype.socket = function (sid
, readable
) {
203 if (!this.sockets
[sid
]) {
204 this.sockets
[sid
] = new Socket(this.manager
, sid
, this, readable
);
207 return this.sockets
[sid
];
211 * Sets authorization for this namespace
216 SocketNamespace
.prototype.authorization = function (fn
) {
222 * Called when a socket disconnects entirely.
227 SocketNamespace
.prototype.handleDisconnect = function (sid
, reason
) {
228 if (this.sockets
[sid
] && this.sockets
[sid
].readable
) {
229 this.sockets
[sid
].onDisconnect(reason
);
234 * Performs authentication.
236 * @param Object client request data
240 SocketNamespace
.prototype.authorize = function (data
, fn
) {
244 this.auth
.call(this, data
, function (err
, authorized
) {
245 self
.log
.debug('client ' +
246 (authorized
? '' : 'un') + 'authorized for ' + self
.name
);
250 this.log
.debug('client authorized for ' + this.name
);
263 SocketNamespace
.prototype.handlePacket = function (sessid
, packet
) {
264 var socket
= this.socket(sessid
)
265 , dataAck
= packet
.ack
== 'data'
269 self
.log
.debug('sending data ack packet');
272 , args
: util
.toArray(arguments
)
277 function error (err
) {
278 self
.log
.warn('handshake error ' + err
+ ' for ' + self
.name
);
279 socket
.packet({ type
: 'error', reason
: err
});
282 function connect () {
283 self
.manager
.onJoin(sessid
, self
.name
);
284 self
.store
.publish('join', sessid
, self
.name
);
287 socket
.packet({ type
: 'connect' });
289 // emit connection event
290 self
.$emit('connection', socket
);
293 switch (packet
.type
) {
295 if (packet
.endpoint
== '') {
298 var manager
= this.manager
299 , handshakeData
= manager
.handshaken
[sessid
];
301 this.authorize(handshakeData
, function (err
, authorized
, newData
) {
302 if (err
) return error(err
);
305 manager
.onHandshake(sessid
, newData
|| handshakeData
);
306 self
.store
.publish('handshake', sessid
, newData
|| handshakeData
);
309 error('unauthorized');
316 if (socket
.acks
[packet
.ackId
]) {
317 socket
.acks
[packet
.ackId
].apply(socket
, packet
.args
);
319 this.log
.info('unknown ack packet');
324 var params
= [packet
.name
].concat(packet
.args
);
329 socket
.$emit
.apply(socket
, params
);
333 this.manager
.onLeave(sessid
, this.name
);
334 this.store
.publish('leave', sessid
, this.name
);
336 socket
.$emit('disconnect', packet
.reason
|| 'packet');
341 var params
= ['message', packet
.data
];
346 socket
.$emit
.apply(socket
, params
);