From 8c3b7d99c2e9a698c73e64b432e6a51b58194611 Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Thu, 2 Jun 2011 05:59:34 -0400 Subject: [PATCH 01/11] fixed some typos; jsonp sets content-type: --- lib/manager.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/manager.js b/lib/manager.js index 5f74386536..aacffa86bd 100644 --- a/lib/manager.js +++ b/lib/manager.js @@ -214,7 +214,7 @@ Manager.prototype.handleRequest = function (req, res) { this.log.debug('ignoring request outside socket.io namespace'); for (var i = 0, l = this.oldListeners.length; i < l; i++) - this.oldListeners[i].call(this, req, res); + this.oldListeners[i].call(this.server, req, res); return; } @@ -441,9 +441,9 @@ Manager.prototype.handleHandshake = function (data, req, res) { ].join(':'); if (data.query.jsonp) - hs = 'io[' + data.query.jsonp + '](' + JSON.stringify(hs) + ');'; + hs = 'io.j[' + data.query.jsonp + '](' + JSON.stringify(hs) + ');'; - res.writeHead(200); + res.writeHead(200, {'content-type': 'application/javascript'}); res.end(hs); }); } else { From 8e590cc8ba1a5550026d058be674ee72deb7ef0a Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Mon, 6 Jun 2011 03:40:01 -0400 Subject: [PATCH 02/11] unshielded error --- lib/manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/manager.js b/lib/manager.js index aeffd39ae8..4a4ae49478 100644 --- a/lib/manager.js +++ b/lib/manager.js @@ -414,7 +414,7 @@ Manager.prototype.handleHandshake = function (data, req, res) { function writeErr (status, message) { if (data.query.jsonp) { res.writeHead(200); - res.end('io.j[' + data.query.jsonp + '](new Error(' + message + '));'); + res.end('io.j[' + data.query.jsonp + '](new Error(' + JSON.stringify(message) + '));'); } else { res.writeHead(status); res.end(message); From 485f2129eb1ef1b6e2038db39ee77740005f53ad Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Wed, 8 Jun 2011 02:05:04 -0400 Subject: [PATCH 03/11] 'event' message fix poc --- lib/parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/parser.js b/lib/parser.js index 483a2be240..273b25e473 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -73,7 +73,7 @@ exports.encodePacket = function (packet) { case 'event': var params = packet.args && packet.args.length ? JSON.stringify(packet.args) : ''; - data = packet.name + (params !== '' ? ('\ufffd' + params) : ''); + data = packet.name + (params !== '' ? ('\ufffc' + params) : ''); break; case 'json': @@ -173,7 +173,7 @@ exports.decodePacket = function (data) { break; case 'event': - var pieces = data.match(/([^\ufffd]+)(\ufffd)?(.*)/); + var pieces = data.match(/([^\ufffc]+)(\ufffc)?(.*)/); packet.name = pieces[1] || ''; packet.args = []; From 942ed48394f8d79902c176b9f6705f277414a9e9 Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Wed, 8 Jun 2011 04:04:16 -0400 Subject: [PATCH 04/11] htmlfile transport aggressively uses _, wiping underscore.js --- lib/transports/htmlfile.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/transports/htmlfile.js b/lib/transports/htmlfile.js index ce23153ce3..3c7c95ae2e 100644 --- a/lib/transports/htmlfile.js +++ b/lib/transports/htmlfile.js @@ -51,7 +51,7 @@ HTMLFile.prototype.handleRequest = function (req) { req.res.write( '' - + '' + + '' + new Array(174).join(' ') ); } @@ -65,7 +65,9 @@ HTMLFile.prototype.handleRequest = function (req) { */ HTMLFile.prototype.write = function (data) { - data = ''; + //DVV: very bad to overwrite global _, it's usually for underscore.js :| + // data = ''; + data = ''; this.drain = false; this.response.write(data); From cb3d8b5f30942d4dfd36c2d48116bf4257dd9846 Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Wed, 8 Jun 2011 04:08:23 -0400 Subject: [PATCH 05/11] remove fired acks --- lib/namespace.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/namespace.js b/lib/namespace.js index efaf49f718..3615714e4c 100644 --- a/lib/namespace.js +++ b/lib/namespace.js @@ -223,6 +223,7 @@ SocketNamespace.prototype.handlePacket = function (sessid, packet) { case 'ack': if (socket.acks[packet.ackId]) { socket.acks[packet.ackId].apply(socket, packet.args); + delete socket.acks[packet.ackId]; } else { this.log.info('unknown ack packet'); } From e648cc0dfe3459bd7009f4956f587ab05acf3b84 Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Wed, 8 Jun 2011 06:36:34 -0400 Subject: [PATCH 06/11] hz --- lib/namespace.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/namespace.js b/lib/namespace.js index 3615714e4c..f587a14e7b 100644 --- a/lib/namespace.js +++ b/lib/namespace.js @@ -223,7 +223,7 @@ SocketNamespace.prototype.handlePacket = function (sessid, packet) { case 'ack': if (socket.acks[packet.ackId]) { socket.acks[packet.ackId].apply(socket, packet.args); - delete socket.acks[packet.ackId]; + //delete socket.acks[packet.ackId]; } else { this.log.info('unknown ack packet'); } From 357dace20bd2cec5d20cee3b77c94d89d625307c Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Fri, 10 Jun 2011 00:37:20 +0400 Subject: [PATCH 07/11] $emit --- lib/socket.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/socket.js b/lib/socket.js index 6080d7e3e4..8b1c935463 100644 --- a/lib/socket.js +++ b/lib/socket.js @@ -284,7 +284,7 @@ Socket.prototype.$emit = EventEmitter.prototype.emit; Socket.prototype.emit = function (ev) { if (events[ev]) { - return EventEmitter.prototype.emit.apply(this, arguments); + return this.$emit.apply(this, arguments); } var args = util.toArray(arguments).slice(1) From 920c6812993dd7f0f028fd6b06be03c5407855bb Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Fri, 10 Jun 2011 03:00:21 -0400 Subject: [PATCH 08/11] guard unset consumer --- lib/socket.js | 2 ++ lib/stores/memory.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/socket.js b/lib/socket.js index 8b1c935463..c1d94e783d 100644 --- a/lib/socket.js +++ b/lib/socket.js @@ -283,6 +283,7 @@ Socket.prototype.$emit = EventEmitter.prototype.emit; */ Socket.prototype.emit = function (ev) { +console.log('DVV:Socket#emit?', arguments); if (events[ev]) { return this.$emit.apply(this, arguments); } @@ -303,5 +304,6 @@ Socket.prototype.emit = function (ev) { packet.args = args; +console.log('DVV:Socket#emit', packet); return this.packet(packet); }; diff --git a/lib/stores/memory.js b/lib/stores/memory.js index b902b31bc6..2077788fcf 100644 --- a/lib/stores/memory.js +++ b/lib/stores/memory.js @@ -283,7 +283,7 @@ Client.prototype.consume = function (fn) { */ Client.prototype.publish = function (msg) { - if (this.paused) { + if (this.paused || !this.consumer) { this.buffer.push(msg); } else { this.consumer(null, msg); From afe0a50e58a48654e1414d168fb96c72b26be466 Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Fri, 10 Jun 2011 04:25:58 -0400 Subject: [PATCH 09/11] fixed unset consumer; fixed connection logic --- lib/manager.js | 2 +- lib/namespace.js | 7 ++----- lib/socket.js | 2 -- lib/stores/memory.js | 5 ++--- lib/transport.js | 16 ++++++++-------- 5 files changed, 13 insertions(+), 19 deletions(-) diff --git a/lib/manager.js b/lib/manager.js index d02ed0ea9e..c47cd5dc37 100644 --- a/lib/manager.js +++ b/lib/manager.js @@ -329,7 +329,7 @@ Manager.prototype.handleClient = function (data, req) { if (count == 1) { // initialize the socket for all namespaces for (var i in self.namespaces) { - self.namespaces[i].socket(data.id, true); + self.handlePacket(data.id, {type: 'connect'}); } // handle packets for the client (all namespaces) diff --git a/lib/namespace.js b/lib/namespace.js index f587a14e7b..9bcf6d2a3c 100644 --- a/lib/namespace.js +++ b/lib/namespace.js @@ -185,9 +185,6 @@ SocketNamespace.prototype.emit = function (name) { SocketNamespace.prototype.socket = function (sid, readable) { if (!this.sockets[sid]) { this.sockets[sid] = new Socket(this.manager, sid, this, readable); - if (this.name === '') { - this.emit('connection', this.sockets[sid]); - } } return this.sockets[sid]; @@ -200,7 +197,7 @@ SocketNamespace.prototype.socket = function (sid, readable) { */ SocketNamespace.prototype.handlePacket = function (sessid, packet) { - var socket = this.socket(sessid) + var socket = this.socket(sessid, true) // readable , dataAck = packet.ack == 'data' , self = this; @@ -216,7 +213,7 @@ SocketNamespace.prototype.handlePacket = function (sessid, packet) { switch (packet.type) { case 'connect': this.store.join(sessid, this.name, function () { - self.emit('connection', self.sockets[sessid]); + self.emit('connection', socket); }); break; diff --git a/lib/socket.js b/lib/socket.js index c1d94e783d..8b1c935463 100644 --- a/lib/socket.js +++ b/lib/socket.js @@ -283,7 +283,6 @@ Socket.prototype.$emit = EventEmitter.prototype.emit; */ Socket.prototype.emit = function (ev) { -console.log('DVV:Socket#emit?', arguments); if (events[ev]) { return this.$emit.apply(this, arguments); } @@ -304,6 +303,5 @@ console.log('DVV:Socket#emit?', arguments); packet.args = args; -console.log('DVV:Socket#emit', packet); return this.packet(packet); }; diff --git a/lib/stores/memory.js b/lib/stores/memory.js index 2077788fcf..461a8df3a0 100644 --- a/lib/stores/memory.js +++ b/lib/stores/memory.js @@ -263,13 +263,12 @@ Client.prototype.count = function (fn) { */ Client.prototype.consume = function (fn) { + this.consumer = fn; this.paused = false; if (this.buffer.length) { fn(this.buffer, null); this.buffer = []; - } else { - this.consumer = fn; } return this; @@ -283,7 +282,7 @@ Client.prototype.consume = function (fn) { */ Client.prototype.publish = function (msg) { - if (this.paused || !this.consumer) { + if (this.paused) { this.buffer.push(msg); } else { this.consumer(null, msg); diff --git a/lib/transport.js b/lib/transport.js index 057c46df6d..0e1dbf3c33 100644 --- a/lib/transport.js +++ b/lib/transport.js @@ -219,12 +219,12 @@ Transport.prototype.setHeartbeatTimeout = function () { var self = this; this.heartbeatTimeout = setTimeout(function () { - self.log.debug('fired heartbeat timeout for client', self.id); +//DVV self.log.debug('fired heartbeat timeout for client', self.id); self.heartbeatTimeout = null; self.end(false, 'heartbeat timeout'); }, this.manager.get('heartbeat timeout') * 1000); - this.log.debug('set heartbeat timeout for client', this.id); +//DVV this.log.debug('set heartbeat timeout for client', this.id); } }; @@ -238,7 +238,7 @@ Transport.prototype.clearHeartbeatTimeout = function () { if (this.heartbeatTimeout) { clearTimeout(this.heartbeatTimeout); this.heartbeatTimeout = null; - this.log.debug('cleared heartbeat timeout for client', this.id); +//DVV this.log.debug('cleared heartbeat timeout for client', this.id); } }; @@ -257,7 +257,7 @@ Transport.prototype.setHeartbeatInterval = function () { self.heartbeat(); }, this.manager.get('heartbeat interval') * 1000); - this.log.debug('set heartbeat interval for client', this.id); +//DVV this.log.debug('set heartbeat interval for client', this.id); } }; @@ -281,7 +281,7 @@ Transport.prototype.clearTimeouts = function () { Transport.prototype.heartbeat = function () { if (this.open) { - this.log.debug('emitting heartbeat for client', this.id); +//DVV this.log.debug('emitting heartbeat for client', this.id); this.packet({ type: 'heartbeat' }); this.setHeartbeatTimeout(); } @@ -298,10 +298,10 @@ Transport.prototype.heartbeat = function () { Transport.prototype.onMessage = function (packet) { if ('heartbeat' == packet.type) { - this.log.debug('got heartbeat packet'); +//DVV this.log.debug('got heartbeat packet'); this.store.heartbeat(this.id); } else if ('disconnect' == packet.type && packet.endpoint == '') { - this.log.debug('got disconnection packet'); +//DVV this.log.debug('got disconnection packet'); this.store.disconnect(this.id, true); } else { this.log.debug('got packet'); @@ -329,7 +329,7 @@ Transport.prototype.clearHeartbeatInterval = function () { if (this.heartbeatInterval) { clearTimeout(this.heartbeatInterval); this.heartbeatInterval = null; - this.log.debug('cleared heartbeat interval for client', this.id); +//DVV this.log.debug('cleared heartbeat interval for client', this.id); } }; From 63850a524ec8aa5e314065939df0ff11e63e4a8a Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Fri, 10 Jun 2011 04:34:21 -0400 Subject: [PATCH 10/11] connection logic --- lib/manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/manager.js b/lib/manager.js index c47cd5dc37..3ad12d4213 100644 --- a/lib/manager.js +++ b/lib/manager.js @@ -329,7 +329,7 @@ Manager.prototype.handleClient = function (data, req) { if (count == 1) { // initialize the socket for all namespaces for (var i in self.namespaces) { - self.handlePacket(data.id, {type: 'connect'}); + self.namespaces[i].handlePacket(data.id, {type: 'connect'}); } // handle packets for the client (all namespaces) From a31a048fe5ae5db2491588861c89a732fab92dc0 Mon Sep 17 00:00:00 2001 From: Vladimir Dronnikov Date: Fri, 10 Jun 2011 23:56:07 +0400 Subject: [PATCH 11/11] added filter() modifier -- useful for smarter selection of sessions to send/emit to. --- lib/namespace.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/namespace.js b/lib/namespace.js index 9bcf6d2a3c..569d65c4db 100644 --- a/lib/namespace.js +++ b/lib/namespace.js @@ -97,6 +97,18 @@ SocketNamespace.prototype.except = function (id) { return this; }; +/** + * Defines a filtering function which should select session ids to + * relay messages to (flag) + * + * @api public + */ + +SocketNamespace.prototype.filter = function (fn) { + this.flags.filter = fn; + return this; +}; + /** * Sets the default flags. * @@ -107,6 +119,7 @@ SocketNamespace.prototype.setFlags = function () { this.flags = { endpoint: this.name , exceptions: [] + , filter: null }; return this; }; @@ -125,7 +138,9 @@ SocketNamespace.prototype.packet = function (packet) { , packet = parser.encodePacket(packet); store.clients(this.flags.endpoint, function (clients) { - clients.forEach(function (id) { + (this.flags.filter ? clients.filter(this.flags.filter) : clients) + .forEach(function (id) { + // N.B. this should be implemented as filtering function if (~exceptions.indexOf(id)) { log.debug('ignoring packet to ', id); return;