Compare commits

...

48 Commits
0.7.7 ... 0.7.8

Author SHA1 Message Date
Guillermo Rauch
65f1399a44 Release 0.7.8 2011-08-08 08:06:30 -07:00
Guillermo Rauch
d86ffcf06d Merge pull request #408 from 3rd-Eden/gc
Garbage collection
2011-08-04 11:50:39 -07:00
Arnout Kazemier
ab5beaff63 Fix 2011-08-04 20:32:49 +02:00
Arnout Kazemier
f0ef33b45f Merge branch 'master' of github.com:LearnBoost/socket.io into gc
Conflicts:
	lib/manager.js
2011-08-04 20:32:43 +02:00
Guillermo Rauch
a4ec5aafa6 Merge pull request #363 from dvv/489bc860d2f050a7925e602a6d16c428f2784b40
small cleanup
2011-07-30 20:32:39 -07:00
Guillermo Rauch
984639ba67 Merge pull request #381 from 3rd-Eden/alias
Added alias for to to in and in to to
2011-07-30 20:27:30 -07:00
Guillermo Rauch
9923c1dee9 Merge branch 'master' of github.com:LearnBoost/socket.io 2011-07-30 20:23:35 -07:00
Guillermo Rauch
1b0a4849df Added test (fixes #380). 2011-07-30 20:21:13 -07:00
Guillermo Rauch
4fc43f322f Changed; make sure sio#listen passes options to both HTTP server and socket.io manager.
Added docs for sio#listen.
2011-07-30 20:20:31 -07:00
Guillermo Rauch
5c0f78ab02 Added options parameter support for Manager constructor. 2011-07-30 20:19:38 -07:00
Guillermo Rauch
d8c7060cc8 Merge pull request #396 from 3rd-Eden/xxs
Potential fix for #372
2011-07-30 18:49:47 -07:00
Guillermo Rauch
b0335b0a61 Merge pull request #339 from 3rd-Eden/333
Don't require redis by default
2011-07-30 18:47:41 -07:00
Guillermo Rauch
a1797ccd4b Merge pull request #337 from 3rd-Eden/handshakeData
Expose path and querystring in handshakeData
2011-07-30 18:47:12 -07:00
Guillermo Rauch
a1c997bc58 Merge pull request #401 from Pita/master
Send response once we got all POST data, not immediately
2011-07-30 18:36:08 -07:00
Guillermo Rauch
0b9b28d251 Merge pull request #409 from 3rd-Eden/bug/407
Fix for #407
2011-07-30 17:59:06 -07:00
Guillermo Rauch
a79b2fa761 Added memory leaks tests. 2011-07-30 17:53:35 -07:00
Guillermo Rauch
195eba74de Added assertvanish dev dependency. 2011-07-30 17:53:22 -07:00
Guillermo Rauch
3edebe5d61 Added test-leaks Makefile task. 2011-07-30 17:53:14 -07:00
Guillermo Rauch
b56389fbc8 Removed auto npm-linking from make test. 2011-07-30 14:46:54 -07:00
Guillermo Rauch
203293db0b Merge pull request #413 from 3rd-Eden/update/package
updated package.json with new build of policyfile and redis
2011-07-30 14:33:09 -07:00
Guillermo Rauch
2b7ea448c4 Merge pull request #416 from 3rd-Eden/test/374
Added testcase to prevent #374 from happening again
2011-07-30 14:32:51 -07:00
Guillermo Rauch
c627f1b7d0 Merge pull request #421 from 3rd-Eden/bug/heartbeat
Make sure that you can disable heart beats
2011-07-30 14:32:34 -07:00
Guillermo Rauch
4c20afd4b7 Merge pull request #346 from ericz/patch-1
Change `;` typo to `,` in first example
2011-07-26 01:48:22 -07:00
Arnout Kazemier
f689434f61 Make sure that you can disable heart beats 2011-07-25 22:12:48 +02:00
Arnout Kazemier
b694ee68c9 Added testcase to prevent #374 from happening again 2011-07-24 13:21:30 +02:00
Guillermo Rauch
8b22ca2ffd Merge pull request #415 from 3rd-Eden/bug/rooms
Bug/rooms
2011-07-24 02:30:36 -07:00
Arnout Kazemier
5c50c4844f fixed missing done() that cuased the suite to timeout 2011-07-24 11:27:43 +02:00
Arnout Kazemier
4fcad6e4bc updated package.json with new build of policyfile and redis 2011-07-23 22:59:32 +02:00
Arnout Kazemier
3b2316e0d8 Fixed rooms memory leak 2011-07-23 22:55:29 +02:00
Arnout Kazemier
a821cce390 Fix for #407 2011-07-22 22:52:20 +02:00
Arnout Kazemier
abe142ac66 Merge branch 'master' of github.com:LearnBoost/socket.io into gc 2011-07-22 21:42:09 +02:00
Arnout Kazemier
5eff0e5ca7 Small clean up, so the the code makes a bit more sense 2011-07-22 21:37:13 +02:00
Guillermo Rauch
c06242efd3 Merge pull request #383 from AD7six/feature/no-duplicate-clients-in-rooms
prevent duplicate references in rooms - probable fix for #379
2011-07-22 07:51:54 -07:00
Peter 'Pita' Martischka
f69f387e1d Send response once we got all POST data, not immediately 2011-07-20 17:29:26 +01:00
Guillermo Rauch
f5c10aec7f Merge pull request #395 from 3rd-Eden/bug/376
Fix for bug #376
2011-07-18 14:12:15 -07:00
Arnout Kazemier
34bd9d9092 Fix for bug #376
Also added unit test to prevent it from happening in the future
2011-07-18 23:06:48 +02:00
Andy Dawson
c30151d03a Remove unused Cl (client) variable.
This test doesn't use any real clients.
2011-07-18 13:22:08 -07:00
Arnout Kazemier
f784c477f0 Potential fix for #372 2011-07-18 22:02:03 +02:00
AD7six
c899c98f31 prevent duplicate references in rooms 2011-07-15 01:13:41 +02:00
Arnout Kazemier
53f0f4d66d Added alias for to to in and in to to 2011-07-14 21:31:55 +02:00
Guillermo Rauch
c826fadb9f Fixed roomClients definition (#378). 2011-07-13 18:30:24 -03:00
Guillermo Rauch
097094cd7a Updated dep [thanks @3rd-Eden] 2011-07-12 05:11:03 -03:00
ericz
27ab98dca4 Fixed typo 2011-07-05 14:26:46 -07:00
Eric Zhang
a8ca11cb47 Change ; typo to , in first example 2011-07-05 14:22:55 -07:00
Arnout Kazemier
15e1e68cfd Merge branch 'master' of github.com:LearnBoost/socket.io into 333 2011-07-04 22:53:20 +02:00
Arnout Kazemier
167da44211 Fixes #333 2011-07-04 22:51:00 +02:00
Arnout Kazemier
1372838092 Expose path and querystring in handshakeData 2011-07-04 19:26:22 +02:00
Vladimir Dronnikov
489bc860d2 cleanup 2011-07-01 09:50:37 -07:00
15 changed files with 409 additions and 41 deletions

View File

@@ -1,4 +1,22 @@
0.7.8 / 2011-08-08
==================
* Changed; make sure sio#listen passes options to both HTTP server and socket.io manager.
* Added docs for sio#listen.
* Added options parameter support for Manager constructor.
* Added memory leaks tests and test-leaks Makefile task.
* Removed auto npm-linking from make test.
* Make sure that you can disable heartbeats. [3rd-Eden]
* Fixed rooms memory leak [3rd-Eden]
* Send response once we got all POST data, not immediately [Pita]
* Fixed onLeave behavior with missing clientsk [3rd-Eden]
* Prevent duplicate references in rooms.
* Added alias for `to` to `in` and `in` to `to`.
* Fixed roomClients definition.
* Removed dependency on redis for installation without npm [3rd-Eden]
* Expose path and querystring in handshakeData [3rd-Eden]
0.7.7 / 2011-07-12
==================

View File

@@ -2,7 +2,6 @@
ALL_TESTS = $(shell find test/ -name '*.test.js')
run-tests:
@npm link > /dev/null --local
@./node_modules/.bin/expresso \
-t 3000 \
-I support \
@@ -17,4 +16,7 @@ test:
test-cov:
@TESTFLAGS=--cov $(MAKE) test
test-leaks:
@ls test/leaks/* | xargs node --expose_debug_as=debug --expose_gc
.PHONY: test

View File

@@ -20,7 +20,7 @@ Next, attach it to a HTTP/HTTPS server. If you're using the fantastic `express`
web framework:
```js
var app = express.createServer();
var app = express.createServer()
, io = io.listen(app);
app.listen(80);

View File

@@ -1,4 +1,3 @@
/*!
* socket.io-node
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
@@ -9,9 +8,7 @@
* Module dependencies.
*/
var http = require('http')
, https = require('https')
, fs = require('fs')
var fs = require('fs')
, url = require('url')
, util = require('./util')
, store = require('./store')
@@ -55,7 +52,7 @@ var parent = module.parent.exports
* @api public
*/
function Manager (server) {
function Manager (server, options) {
this.server = server;
this.namespaces = {};
this.sockets = this.of('');
@@ -83,6 +80,10 @@ function Manager (server) {
, 'client store expiration': 15
};
for (var i in options) {
this.settings[i] = options[i];
}
this.initStore();
// reset listeners
@@ -99,6 +100,13 @@ function Manager (server) {
self.handleUpgrade(req, socket, head);
});
server.on('close', function () {
clearInterval(self.gc);
});
// run our private gc every 10 seconds
this.gc = setInterval(this.garbageCollection.bind(this), 10000);
for (var i in transports) {
if (transports[i].init) {
transports[i].init(this);
@@ -347,15 +355,17 @@ Manager.prototype.onDispatch = function (room, packet, volatile, exceptions) {
Manager.prototype.onJoin = function (id, name) {
if (!this.roomClients[id]) {
this.roomClients[id] = [];
this.roomClients[id] = {};
}
if (!this.rooms[name]) {
this.rooms[name] = [];
}
this.rooms[name].push(id);
this.roomClients[id][name] = true;
if (!~this.rooms[name].indexOf(id)) {
this.rooms[name].push(id);
this.roomClients[id][name] = true;
}
};
/**
@@ -366,7 +376,15 @@ Manager.prototype.onJoin = function (id, name) {
Manager.prototype.onLeave = function (id, room) {
if (this.rooms[room]) {
this.rooms[room].splice(this.rooms[room].indexOf(id), 1);
var index = this.rooms[room].indexOf(id);
if (index >= 0) {
this.rooms[room].splice(index, 1);
}
if (!this.rooms[room].length) {
delete this.rooms[room];
}
delete this.roomClients[id][room];
}
};
@@ -425,13 +443,13 @@ Manager.prototype.onClientMessage = function (id, packet) {
*/
Manager.prototype.onClientDisconnect = function (id, reason) {
this.onDisconnect(id);
for (var name in this.namespaces) {
if (this.roomClients[id][name]) {
this.namespaces[name].handleDisconnect(id, reason);
}
}
this.onDisconnect(id);
};
/**
@@ -463,8 +481,9 @@ Manager.prototype.onDisconnect = function (id, local) {
if (this.roomClients[id]) {
for (var room in this.roomClients[id]) {
this.rooms[room].splice(this.rooms[room].indexOf(id), 1);
this.onLeave(id, room);
}
delete this.roomClients[id]
}
this.store.destroyClient(id, this.get('client store expiration'));
@@ -581,9 +600,10 @@ Manager.prototype.handleClient = function (data, req) {
return;
}
var transport = new transports[data.transport](this, data, req);
var transport = new transports[data.transport](this, data, req)
, handshaken = this.handshaken[data.id];
if (this.handshaken[data.id]) {
if (handshaken) {
if (transport.open) {
if (this.closed[data.id] && this.closed[data.id].length) {
transport.payload(this.closed[data.id]);
@@ -599,6 +619,11 @@ Manager.prototype.handleClient = function (data, req) {
this.onConnect(data.id);
this.store.publish('connect', data.id);
// flag as used
delete handshaken.issued;
this.onHandshake(data.id, handshaken);
this.store.publish('handshake', data.id, handshaken);
// initialize the socket for all namespaces
for (var i in this.namespaces) {
var socket = this.namespaces[i].socket(data.id, true);
@@ -773,7 +798,7 @@ Manager.prototype.handleHandshake = function (data, req, res) {
var id = self.generateId()
, hs = [
id
, self.get('heartbeat timeout') || ''
, self.enabled('heartbeats') ? self.get('heartbeat timeout') || '' : ''
, self.get('close timeout') || ''
, self.transports(data).join(',')
].join(':');
@@ -806,7 +831,8 @@ Manager.prototype.handleHandshake = function (data, req, res) {
Manager.prototype.handshakeData = function (data) {
var connection = data.request.connection
, connectionAddress;
, connectionAddress
, date = new Date;
if (connection.remoteAddress) {
connectionAddress = {
@@ -823,9 +849,12 @@ Manager.prototype.handshakeData = function (data) {
return {
headers: data.headers
, address: connectionAddress
, time: (new Date).toString()
, time: date.toString()
, query: data.query
, url: data.request.url
, xdomain: !!data.request.headers.origin
, secure: data.request.connection.secure
, issued: +date
};
};
@@ -955,6 +984,8 @@ Manager.prototype.checkRequest = function (req) {
/**
* Declares a socket namespace
*
* @api public
*/
Manager.prototype.of = function (nsp) {
@@ -964,3 +995,26 @@ Manager.prototype.of = function (nsp) {
return this.namespaces[nsp] = new SocketNamespace(this, nsp);
};
/**
* Perform garbage collection on long living objects and properties that cannot
* be removed automatically.
*
* @api private
*/
Manager.prototype.garbageCollection = function () {
// clean up unused handshakes
var ids = Object.keys(this.handshaken)
, i = ids.length
, now = Date.now()
, handshake;
while (i--) {
handshake = this.handshaken[ids[i]];
if ('issued' in handshake && (now - handshake.issued) >= 3E4) {
this.onDisconnect(ids[i]);
}
}
};

View File

@@ -108,7 +108,7 @@ SocketNamespace.prototype.__defineGetter__('volatile', function () {
* @api public
*/
SocketNamespace.prototype.in = function (room) {
SocketNamespace.prototype.in = SocketNamespace.prototype.to = function (room) {
this.flags.endpoint = this.name + (room ? '/' + room : '');
return this;
};
@@ -227,6 +227,7 @@ SocketNamespace.prototype.authorization = function (fn) {
SocketNamespace.prototype.handleDisconnect = function (sid, reason) {
if (this.sockets[sid] && this.sockets[sid].readable) {
this.sockets[sid].onDisconnect(reason);
delete this.sockets[sid];
}
};

View File

@@ -15,7 +15,7 @@ var client = require('socket.io-client');
* Version.
*/
exports.version = '0.7.7';
exports.version = '0.7.8';
/**
* Supported protocol version.
@@ -32,6 +32,9 @@ exports.clientVersion = client.version;
/**
* Attaches a manager
*
* @param {HTTPServer/Number} a HTTP/S server or a port number to listen on.
* @param {Object} opts to be passed to Manager and/or http server
* @param {Function} callback if a port is supplied
* @api public
*/
@@ -65,7 +68,7 @@ exports.listen = function (server, options, fn) {
}
// otherwise assume a http/s server
return new exports.Manager(server);
return new exports.Manager(server, options);
};
/**

View File

@@ -106,7 +106,7 @@ Socket.prototype.__defineGetter__('broadcast', function () {
* @api public
*/
Socket.prototype.to = function (room) {
Socket.prototype.to = Socket.prototype.in = function (room) {
this.flags.room = room;
return this;
};

View File

@@ -11,8 +11,7 @@
var crypto = require('crypto')
, Store = require('../store')
, assert = require('assert')
, redis = require('redis');
, assert = require('assert');
/**
* Exports the constructor.
@@ -25,6 +24,7 @@ Redis.Client = Client;
* Redis store.
* Options:
* - nodeId (fn) gets an id that uniquely identifies this node
* - redis (fn) redis constructor, defaults to redis
* - redisPub (object) options to pass to the pub redis client
* - redisSub (object) options to pass to the sub redis client
* - redisClient (object) options to pass to the general redis client
@@ -60,6 +60,8 @@ function Redis (opts) {
}
}
var redis = opts.redis || require('redis');
// initialize a pubsub client and a regular client
this.pub = redis.createClient(opts.redisPub);
this.sub = redis.createClient(opts.redisSub);

View File

@@ -259,7 +259,7 @@ Transport.prototype.clearCloseTimeout = function () {
*/
Transport.prototype.setHeartbeatTimeout = function () {
if (!this.heartbeatTimeout) {
if (!this.heartbeatTimeout && this.manager.enabled('heartbeats')) {
var self = this;
this.heartbeatTimeout = setTimeout(function () {
@@ -279,7 +279,7 @@ Transport.prototype.setHeartbeatTimeout = function () {
*/
Transport.prototype.clearHeartbeatTimeout = function () {
if (this.heartbeatTimeout) {
if (this.heartbeatTimeout && this.manager.enabled('heartbeats')) {
clearTimeout(this.heartbeatTimeout);
this.heartbeatTimeout = null;
this.log.debug('cleared heartbeat timeout for client', this.id);
@@ -294,7 +294,7 @@ Transport.prototype.clearHeartbeatTimeout = function () {
*/
Transport.prototype.setHeartbeatInterval = function () {
if (!this.heartbeatInterval) {
if (!this.heartbeatInterval && this.manager.enabled('heartbeats')) {
var self = this;
this.heartbeatInterval = setTimeout(function () {
@@ -398,7 +398,7 @@ Transport.prototype.onMessage = function (packet) {
*/
Transport.prototype.clearHeartbeatInterval = function () {
if (this.heartbeatInterval) {
if (this.heartbeatInterval && this.manager.enabled('heartbeats')) {
clearTimeout(this.heartbeatInterval);
this.heartbeatInterval = null;
this.log.debug('cleared heartbeat interval for client', this.id);

View File

@@ -54,6 +54,9 @@ HTTPTransport.prototype.handleRequest = function (req) {
});
req.on('end', function () {
res.writeHead(200, headers);
res.end('1');
self.onData(self.postEncoded ? qs.parse(buffer).d : buffer);
});
@@ -65,9 +68,6 @@ HTTPTransport.prototype.handleRequest = function (req) {
headers['Access-Control-Allow-Credentials'] = 'true';
}
}
res.writeHead(200, headers);
res.end('1');
} else {
this.response = req.res;

View File

@@ -70,6 +70,7 @@ JSONPPolling.prototype.doWrite = function (data) {
'Content-Type': 'text/javascript; charset=UTF-8'
, 'Content-Length': Buffer.byteLength(data)
, 'Connection': 'Keep-Alive'
, 'X-XSS-Protection': '0'
});
this.response.write(data);

View File

@@ -1,6 +1,6 @@
{
"name": "socket.io"
, "version": "0.7.7"
, "version": "0.7.8"
, "description": "Real-time apps made cross-browser & easy with a WebSocket-like API"
, "homepage": "http://socket.io"
, "keywords": ["websocket", "socket", "realtime", "socket.io", "comet", "ajax"]
@@ -15,13 +15,14 @@
, "url": "https://github.com/LearnBoost/Socket.IO-node.git"
}
, "dependencies": {
"socket.io-client": "0.7.4"
, "policyfile": "0.0.3"
, "redis": "0.6.0"
"socket.io-client": "0.7.5"
, "policyfile": "0.0.4"
, "redis": "0.6.6"
}
, "devDependencies": {
"expresso": "0.7.7"
, "should": "0.0.4"
, "assertvanish": "0.0.3-1"
}
, "main": "index"
, "engines": { "node": ">= 0.4.0" }

View File

@@ -0,0 +1,54 @@
/*!
* socket.io-node
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
* MIT Licensed
*/
/**
* Test dependencies.
*/
require.paths.unshift(__dirname + '/../../lib');
var assertvanish = require('assertvanish')
, common = require('../common')
, ports = 15800;
function resultCallback (leaks, leakedSocket) {
if (leaks) {
console.error('Leak detected');
process.exit(1);
} else {
console.error('No leaks');
process.exit(0);
}
};
/**
* Test.
*/
var cl = client(++ports);
var io = create(cl);
io.sockets.on('connection', function (socket) {
console.log('connected');
socket.on('disconnect', function() {
console.log("client gone");
setTimeout(gc, 1000);
assertvanish(socket, 2000, {silent: true, callback: resultCallback});
});
});
setTimeout(function() {
cl.handshake(function (sid) {
var ws = websocket(cl, sid);
ws.on('open', function () {
console.log('open!');
setTimeout(function() {
ws.close();
}, 500);
});
});
}, 100);

View File

@@ -1,4 +1,3 @@
/*!
* socket.io-node
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
@@ -21,6 +20,22 @@ var sio = require('socket.io')
module.exports = {
'test setting and getting a configuration flag': function (done) {
var port = ++ports
, io = sio.listen(http.createServer());
io.set('a', 'b');
io.get('a').should.eql('b');
var port = ++ports
, io = sio.listen(http.createServer());
io.configure(function () {
io.set('a', 'b');
io.enable('tobi');
});
io.get('a').should.eql('b');
done();
},
@@ -37,11 +52,9 @@ module.exports = {
, io = sio.listen(http.createServer());
io.configure(function () {
io.set('a', 'b');
io.enable('tobi');
});
io.get('a').should.eql('b');
io.enabled('tobi').should.be.true;
done();
@@ -534,6 +547,100 @@ module.exports = {
io.server.close();
done();
});
}
},
'test disabling heartbeats': function (done) {
var port = ++ports
, io = sio.listen(port)
, cl = client(port)
, messages = 0
, beat = false
, ws;
io.configure(function () {
io.disable('heartbeats');
io.set('heartbeat interval', .05);
io.set('heartbeat timeout', .05);
io.set('close timeout', .05);
});
io.sockets.on('connection', function (socket) {
setTimeout(function () {
socket.disconnect();
}, io.get('heartbeat timeout') * 1000 + 100);
socket.on('disconnect', function (reason) {
beat.should.be.false;
cl.end();
ws.finishClose();
io.server.close();
done();
});
});
cl.get('/socket.io/{protocol}/', function (res, data) {
res.statusCode.should.eql(200);
data.should.match(/([^:]+)::[\.0-9]+:(.*)/);
cl.handshake(function (sid) {
ws = websocket(cl, sid);
ws.on('message', function (packet) {
if (++messages == 1) {
packet.type.should.eql('connect');
} else if (packet.type == 'heartbeat'){
beat = true;
}
});
});
});
},
'no duplicate room members': function (done) {
var port = ++ports
, io = sio.listen(port);
Object.keys(io.rooms).length.should.equal(0);
io.onJoin(123, 'foo');
io.rooms.foo.length.should.equal(1);
io.onJoin(123, 'foo');
io.rooms.foo.length.should.equal(1);
io.onJoin(124, 'foo');
io.rooms.foo.length.should.equal(2);
io.onJoin(124, 'foo');
io.rooms.foo.length.should.equal(2);
io.onJoin(123, 'bar');
io.rooms.foo.length.should.equal(2);
io.rooms.bar.length.should.equal(1);
io.onJoin(123, 'bar');
io.rooms.foo.length.should.equal(2);
io.rooms.bar.length.should.equal(1);
io.onJoin(124, 'bar');
io.rooms.foo.length.should.equal(2);
io.rooms.bar.length.should.equal(2);
io.onJoin(124, 'bar');
io.rooms.foo.length.should.equal(2);
io.rooms.bar.length.should.equal(2);
io.server.close();
done();
},
'test passing options directly to the Manager through listen': function (done) {
var port = ++ports
, io = sio.listen(port, { resource: '/my resource', custom: 'opt' });
io.get('resource').should.equal('/my resource');
io.get('custom').should.equal('opt');
io.server.close();
done();
}
};

View File

@@ -899,6 +899,59 @@ module.exports = {
});
},
'test leaving a room': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, io = create(cl1)
, joins = 0
, disconnects = 0;
io.set('close timeout', 0);
io.sockets.on('connection', function (socket) {
socket.join('foo');
io.sockets.clients('foo').should.have.length(++joins);
socket.on('disconnect', function () {
socket.leave('foo');
socket.leave('foo');
socket.leave('foo');
io.sockets.clients('foo').should.have.length(--joins);
if (++disconnects == 2) {
io.server.close();
cl1.end();
cl2.end();
done();
}
})
});
cl1.handshake(function (sid) {
var ws1 = websocket(cl1, sid);
ws1.on('message', function (msg) {
if (!ws1.connected) {
msg.type.should.eql('connect');
ws1.connected = true;
ws1.finishClose();
}
});
});
cl2.handshake(function (sid) {
var ws2 = websocket(cl2, sid);
ws2.on('message', function (msg) {
if (!ws2.connected) {
msg.type.should.eql('connect');
ws2.connected = true;
ws2.finishClose();
}
});
});
},
'test message with broadcast flag': function (done) {
var port = ++ports
, cl1 = client(port)
@@ -1584,6 +1637,42 @@ module.exports = {
});
},
'test accessing handshake data from sockets on disconnect': function (done) {
var cl = client(++ports)
, io = create(cl)
, ws;
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function () {
(!!socket.handshake.address.address).should.be.true;
(!!socket.handshake.address.port).should.be.true;
socket.handshake.headers.host.should.equal('localhost');
socket.handshake.headers.connection.should.equal('keep-alive');
socket.handshake.time.should.match(/GMT/);
setTimeout(function () {
ws.finishClose();
cl.end();
io.server.close();
done();
}, 10);
});
socket.disconnect();
});
cl.handshake(function (sid) {
ws = websocket(cl, sid);
ws.on('message', function (msg) {
if (!ws.connected) {
msg.type.should.eql('connect');
ws.connected = true;
}
});
});
},
'test for intentional and unintentional disconnects': function (done) {
var cl = client(++ports)
, io = create(cl)
@@ -1642,5 +1731,41 @@ module.exports = {
}
});
});
}
},
'test socket clean up': function (done) {
var cl = client(++ports)
, io = create(cl)
, ws;
io.sockets.on('connection', function (socket) {
var self = this
, id = socket.id;
socket.on('disconnect', function () {
setTimeout(function () {
var available = !!self.sockets[id];
available.should.be.false;
ws.finishClose();
cl.end();
io.server.close();
done();
}, 10);
});
socket.disconnect();
});
cl.handshake(function (sid) {
ws = websocket(cl, sid);
ws.on('message', function (msg) {
if (!ws.connected) {
msg.type.should.eql('connect');
ws.connected = true;
}
});
});
},
};