NewsBlur/node/node_modules/socket.io/test/transports.websocket.test.js
2012-01-02 18:22:06 -08:00

1811 lines
43 KiB
JavaScript

/*!
* socket.io-node
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
* MIT Licensed
*/
/**
* Test dependencies.
*/
var sio = require('socket.io')
, should = require('./common')
, parser = sio.parser
, ports = 15800;
/**
* Tests.
*/
module.exports = {
'websocket identifies as websocket': function (done) {
var cl = client(++ports)
, io = create(cl)
, ws;
io.set('transports', ['websocket']);
io.sockets.on('connection', function (socket) {
socket.manager.transports[socket.id].name.should.equal('websocket');
ws.finishClose();
cl.end();
io.server.close();
done();
});
cl.handshake(function (sid) {
ws = websocket(cl, sid);
});
},
'default websocket draft parser is used for unknown sec-websocket-version': function (done) {
var cl = client(++ports)
, io = create(cl)
, ws;
io.set('transports', ['websocket']);
io.sockets.on('connection', function (socket) {
socket.manager.transports[socket.id].protocolVersion.should.equal('hixie-76');
ws.finishClose();
cl.end();
io.server.close();
done();
});
cl.handshake(function (sid) {
ws = websocket(cl, sid);
});
},
'hybi-07-12 websocket draft parser is used for sec-websocket-version: 8': function (done) {
var cl = client(++ports)
, io = create(cl);
io.set('transports', ['websocket']);
io.sockets.on('connection', function (socket) {
socket.manager.transports[socket.id].protocolVersion.should.equal('07-12');
cl.end();
io.server.close();
done();
});
var headers = {
'sec-websocket-version': 8,
'upgrade': 'websocket',
'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ=='
}
cl.get('/socket.io/{protocol}', {}, function (res, data) {
var sid = data.split(':')[0];
var url = '/socket.io/' + sio.protocol + '/websocket/' + sid;
cl.get(url, {headers: headers}, function (res, data) {});
});
},
'hybi-16 websocket draft parser is used for sec-websocket-version: 13': function (done) {
var cl = client(++ports)
, io = create(cl)
io.set('transports', ['websocket']);
io.sockets.on('connection', function (socket) {
socket.manager.transports[socket.id].protocolVersion.should.equal('16');
cl.end();
io.server.close();
done();
});
var headers = {
'sec-websocket-version': 13,
'upgrade': 'websocket',
'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ=='
}
cl.get('/socket.io/{protocol}', {}, function (res, data) {
var sid = data.split(':')[0];
var url = '/socket.io/' + sio.protocol + '/websocket/' + sid;
cl.get(url, {headers: headers}, function (res, data) {});
});
},
'hybi-07-12 origin filter blocks access for mismatched sec-websocket-origin': function (done) {
var cl = client(++ports)
, io = create(cl)
io.set('transports', ['websocket']);
io.set('origins', 'foo.bar.com:*');
var headers = {
'sec-websocket-version': 8,
'upgrade': 'websocket',
'Sec-WebSocket-Origin': 'http://baz.bar.com',
'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ=='
}
// handshake uses correct origin -- we want to block the actuall websocket call
cl.get('/socket.io/{protocol}', {headers: {origin: 'http://foo.bar.com'}}, function (res, data) {
var sid = data.split(':')[0];
var url = '/socket.io/' + sio.protocol + '/websocket/' + sid;
cl.get(url, {headers: headers}, function (res, data) {});
cl.end();
io.server.close();
done();
});
},
'hybi-16 origin filter blocks access for mismatched sec-websocket-origin': function (done) {
var cl = client(++ports)
, io = create(cl)
io.set('transports', ['websocket']);
io.set('origins', 'foo.bar.com:*');
var headers = {
'sec-websocket-version': 13,
'upgrade': 'websocket',
'origin': 'http://baz.bar.com',
'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ=='
}
// handshake uses correct origin -- we want to block the actuall websocket call
cl.get('/socket.io/{protocol}', {headers: {origin: 'http://foo.bar.com'}}, function (res, data) {
var sid = data.split(':')[0];
var url = '/socket.io/' + sio.protocol + '/websocket/' + sid;
cl.get(url, {headers: headers}, function (res, data) {});
cl.end();
io.server.close();
done();
});
},
'test that not responding to a heartbeat drops client': function (done) {
var cl = client(++ports)
, io = create(cl)
, messages = 0
, ws;
io.configure(function () {
io.set('heartbeat interval', .05);
io.set('heartbeat timeout', .05);
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function (reason) {
beat.should.be.true;
reason.should.eql('heartbeat timeout');
cl.end();
ws.finishClose();
io.server.close();
done();
});
});
cl.handshake(function (sid) {
ws = websocket(cl, sid);
ws.on('message', function (packet) {
if (++messages == 1) {
packet.type.should.eql('connect');
} else {
packet.type.should.eql('heartbeat');
beat = true;
}
});
});
},
'test that responding to a heartbeat maintains session': function (done) {
var cl = client(++ports)
, io = create(cl)
, messages = 0
, heartbeats = 0
, ws;
io.configure(function () {
io.set('heartbeat interval', .05);
io.set('heartbeat timeout', .05);
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function (reason) {
heartbeats.should.eql(2);
reason.should.eql('heartbeat timeout');
cl.end();
ws.finishClose();
io.server.close();
done();
});
});
cl.handshake(function (sid) {
ws = websocket(cl, sid);
ws.on('message', function (packet) {
if (++messages == 1) {
packet.type.should.eql('connect');
} else {
packet.type.should.eql('heartbeat');
heartbeats++;
if (heartbeats == 1) {
ws.packet({ type: 'heartbeat' });
}
}
});
});
},
'test sending deliverable volatile messages': function (done) {
var cl = client(++ports)
, io = create(cl)
, messages = 0
, messaged = false;
io.configure(function () {
io.set('close timeout', .05);
});
io.sockets.on('connection', function (socket) {
socket.volatile.send('tobi');
socket.on('disconnect', function () {
messaged.should.be.true;
cl.end();
io.server.close();
done();
});
});
cl.handshake(function (sid) {
var ws = websocket(cl, sid);
ws.on('message', function (msg) {
if (++messages == 1) {
msg.type.should.eql('connect');
} else {
msg.should.eql({
type: 'message'
, data: 'tobi'
, endpoint: ''
});
messaged = true;
ws.finishClose();
}
});
});
},
'test sending deliverable volatile json': function (done) {
var cl = client(++ports)
, io = create(cl)
, messaged = false;
io.configure(function () {
io.set('close timeout', .05);
});
io.sockets.on('connection', function (socket) {
socket.volatile.json.send([1, 2, 3]);
socket.on('disconnect', function () {
messaged.should.be.true;
cl.end();
io.server.close();
done();
});
});
cl.handshake(function (sid) {
var ws = websocket(cl, sid);
ws.on('message', function (msg) {
if (!ws.connected) {
msg.type.should.eql('connect');
ws.connected = true;
} else {
msg.should.eql({
type: 'json'
, data: [1, 2, 3]
, endpoint: ''
});
messaged = true;
ws.finishClose();
}
});
});
},
'test sending deliverable volatile events': function (done) {
var cl = client(++ports)
, io = create(cl)
, messaged = false;
io.configure(function () {
io.set('close timeout', .05);
});
io.sockets.on('connection', function (socket) {
socket.volatile.emit('tobi');
socket.on('disconnect', function () {
messaged.should.be.true;
cl.end();
io.server.close();
done();
});
});
cl.handshake(function (sid) {
var ws = websocket(cl, sid);
ws.on('message', function (msg) {
if (!ws.connected) {
msg.type.should.eql('connect');
ws.connected = true;
} else {
msg.should.eql({
type: 'event'
, name: 'tobi'
, endpoint: ''
, args: []
});
messaged = true;
ws.finishClose();
}
});
});
},
'test sending to all clients in a namespace': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, io = create(cl1)
, messages = 0
, connections = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
connections++;
if (connections == 2) {
io.sockets.send('yup');
}
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 2) {
messages.should.eql(2);
cl1.end();
cl2.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'message'
, data: 'yup'
, endpoint: ''
});
messages++;
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;
} else {
msg.should.eql({
type: 'message'
, data: 'yup'
, endpoint: ''
});
messages++;
ws2.finishClose();
}
});
});
},
'test sending json to all clients in a namespace': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, io = create(cl1)
, messages = 0
, connections = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
connections++;
if (connections == 2) {
io.sockets.json.send({ a: 'b' });
}
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 2) {
messages.should.eql(2);
cl1.end();
cl2.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'json'
, data: { a: 'b' }
, endpoint: ''
});
messages++;
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;
} else {
msg.should.eql({
type: 'json'
, data: { a: 'b' }
, endpoint: ''
});
messages++;
ws2.finishClose();
}
});
});
},
'test emitting to all clients in a namespace': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, io = create(cl1)
, messages = 0
, connections = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
connections++;
if (connections == 2) {
io.sockets.emit('tobi', 'rapture');
}
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 2) {
messages.should.eql(2);
cl1.end();
cl2.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'event'
, name: 'tobi'
, args: ['rapture']
, endpoint: ''
});
messages++;
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;
} else {
msg.should.eql({
type: 'event'
, name: 'tobi'
, args: ['rapture']
, endpoint: ''
});
messages++;
ws2.finishClose();
}
});
});
},
'test sending to all clients in a room': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, cl3 = client(port)
, io = create(cl1)
, messages = 0
, joins = 0
, connections = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
connections++;
if (connections != 3) {
socket.join('woot');
joins++;
if (joins == 2) {
setTimeout(function () {
connections.should.eql(3);
io.sockets.in('woot').send('hahaha');
}, 20);
}
}
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 3) {
messages.should.eql(2);
cl1.end();
cl2.end();
cl3.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'message'
, data: 'hahaha'
, endpoint: ''
});
messages++;
}
});
setTimeout(function () {
ws1.finishClose();
}, 50);
});
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;
} else {
msg.should.eql({
type: 'message'
, data: 'hahaha'
, endpoint: ''
});
messages++;
}
});
setTimeout(function () {
ws2.finishClose();
}, 50);
});
cl3.handshake(function (sid) {
var ws3 = websocket(cl3, sid);
ws3.on('message', function (msg) {
if (!ws3.connected) {
msg.type.should.eql('connect');
ws3.connected = true;
} else {
msg.should.eql({
type: 'message'
, data: 'hahaha'
, endpoint: ''
});
messages++;
}
});
setTimeout(function () {
ws3.finishClose();
}, 50);
});
},
'test sending json to all clients in a room': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, cl3 = client(port)
, io = create(cl1)
, messages = 0
, joins = 0
, connections = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
connections++;
if (connections != 3) {
socket.join('woot');
joins++;
if (joins == 2) {
setTimeout(function () {
connections.should.eql(3);
io.sockets.in('woot').json.send(123);
}, 20);
}
}
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 3) {
messages.should.eql(2);
cl1.end();
cl2.end();
cl3.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'json'
, data: 123
, endpoint: ''
});
messages++;
}
});
setTimeout(function () {
ws1.finishClose();
}, 50);
});
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;
} else {
msg.should.eql({
type: 'json'
, data: 123
, endpoint: ''
});
messages++;
}
});
setTimeout(function () {
ws2.finishClose();
}, 50);
});
cl3.handshake(function (sid) {
var ws3 = websocket(cl3, sid);
ws3.on('message', function (msg) {
if (!ws3.connected) {
msg.type.should.eql('connect');
ws3.connected = true;
} else {
msg.should.eql({
type: 'json'
, data: 123
, endpoint: ''
});
messages++;
}
});
setTimeout(function () {
ws3.finishClose();
}, 50);
});
},
'test emitting to all clients in a room': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, cl3 = client(port)
, io = create(cl1)
, messages = 0
, joins = 0
, connections = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
connections++;
if (connections != 3) {
socket.join('woot');
joins++;
if (joins == 2) {
setTimeout(function () {
connections.should.eql(3);
io.sockets.in('woot').emit('locki');
}, 20);
}
}
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 3) {
messages.should.eql(2);
cl1.end();
cl2.end();
cl3.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'event'
, name: 'locki'
, args: []
, endpoint: ''
});
messages++;
}
});
setTimeout(function () {
ws1.finishClose();
}, 50);
});
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;
} else {
msg.should.eql({
type: 'event'
, name: 'locki'
, args: []
, endpoint: ''
});
messages++;
}
});
setTimeout(function () {
ws2.finishClose();
}, 50);
});
cl3.handshake(function (sid) {
var ws3 = websocket(cl3, sid);
ws3.on('message', function (msg) {
if (!ws3.connected) {
msg.type.should.eql('connect');
ws3.connected = true;
} else {
msg.should.eql({
type: 'event'
, name: 'locki'
, args: []
, endpoint: ''
});
messages++;
}
});
setTimeout(function () {
ws3.finishClose();
}, 50);
});
},
'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)
, cl2 = client(port)
, cl3 = client(port)
, io = create(cl1)
, messages = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
socket.on('trigger broadcast', function () {
socket.broadcast.send('boom');
});
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 3) {
messages.should.eql(2);
cl1.end();
cl2.end();
cl3.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'message'
, data: 'boom'
, endpoint: ''
});
messages++;
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;
} else {
msg.should.eql({
type: 'message'
, data: 'boom'
, endpoint: ''
});
messages++;
ws2.finishClose();
}
});
});
cl3.handshake(function (sid) {
var ws3 = websocket(cl3, sid);
ws3.on('open', function () {
ws3.packet({
type: 'event'
, name: 'trigger broadcast'
, endpoint: ''
});
setTimeout(function () {
ws3.finishClose();
}, 50);
});
ws3.on('message', function (msg) {
if (!ws3.connected) {
msg.type.should.eql('connect');
ws3.connected = true;
} else {
throw new Error('we shouldnt get a message here');
}
});
});
},
'test json with broadcast flag': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, cl3 = client(port)
, io = create(cl1)
, messages = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
socket.on('trigger broadcast', function () {
socket.broadcast.json.send([1, 2, 3]);
});
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 3) {
messages.should.eql(2);
cl1.end();
cl2.end();
cl3.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'json'
, data: [1, 2, 3]
, endpoint: ''
});
messages++;
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;
} else {
msg.should.eql({
type: 'json'
, data: [1, 2, 3]
, endpoint: ''
});
messages++;
ws2.finishClose();
}
});
});
cl3.handshake(function (sid) {
var ws3 = websocket(cl3, sid);
ws3.on('open', function () {
ws3.packet({
type: 'event'
, name: 'trigger broadcast'
, endpoint: ''
});
setTimeout(function () {
ws3.finishClose();
}, 50);
});
ws3.on('message', function (msg) {
if (!ws3.connected) {
msg.type.should.eql('connect');
ws3.connected = true;
} else {
throw new Error('we shouldnt get a message here');
}
});
});
},
'test event with broadcast flag': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, cl3 = client(port)
, io = create(cl1)
, messages = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
socket.on('trigger broadcast', function () {
socket.broadcast.emit('hey', 'arnold');
});
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 3) {
messages.should.eql(2);
cl1.end();
cl2.end();
cl3.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'event'
, name: 'hey'
, args: ['arnold']
, endpoint: ''
});
messages++;
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;
} else {
msg.should.eql({
type: 'event'
, name: 'hey'
, args: ['arnold']
, endpoint: ''
});
messages++;
ws2.finishClose();
}
});
});
cl3.handshake(function (sid) {
var ws3 = websocket(cl3, sid);
ws3.on('open', function () {
ws3.packet({
type: 'event'
, name: 'trigger broadcast'
, endpoint: ''
});
setTimeout(function () {
ws3.finishClose();
}, 50);
});
ws3.on('message', function (msg) {
if (!ws3.connected) {
msg.type.should.eql('connect');
ws3.connected = true;
} else {
throw new Error('we shouldnt get a message here');
}
});
});
},
'test message with broadcast flag and to()': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, cl3 = client(port)
, io = create(cl1)
, messages = 0
, connections = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
connections++;
if (connections == 1) {
socket.join('losers');
}
socket.on('trigger broadcast', function () {
socket.broadcast.to('losers').send('boom');
});
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 3) {
messages.should.eql(1);
cl1.end();
cl2.end();
cl3.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'message'
, data: 'boom'
, endpoint: ''
});
messages++;
}
});
ws1.on('open', function () {
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;
} else {
throw new Error('This socket shouldnt get a message');
}
});
ws2.on('open', function () {
cl3.handshake(function (sid) {
var ws3 = websocket(cl3, sid);
ws3.on('open', function () {
ws3.packet({
type: 'event'
, name: 'trigger broadcast'
, endpoint: ''
});
setTimeout(function () {
ws1.finishClose();
ws2.finishClose();
ws3.finishClose();
}, 50);
});
ws3.on('message', function (msg) {
if (!ws3.connected) {
msg.type.should.eql('connect');
ws3.connected = true;
} else {
throw new Error('we shouldnt get a message here');
}
});
});
});
});
});
});
},
'test json with broadcast flag and to()': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, cl3 = client(port)
, io = create(cl1)
, messages = 0
, connections = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
connections++;
if (connections == 1) {
socket.join('losers');
}
socket.on('trigger broadcast', function () {
socket.broadcast.json.to('losers').send({ hello: 'world' });
});
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 3) {
messages.should.eql(1);
cl1.end();
cl2.end();
cl3.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'json'
, data: { hello: 'world' }
, endpoint: ''
});
messages++;
}
});
ws1.on('open', function () {
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;
} else {
throw new Error('This socket shouldnt get a message');
}
});
ws2.on('open', function () {
cl3.handshake(function (sid) {
var ws3 = websocket(cl3, sid);
ws3.on('open', function () {
ws3.packet({
type: 'event'
, name: 'trigger broadcast'
, endpoint: ''
});
setTimeout(function () {
ws1.finishClose();
ws2.finishClose();
ws3.finishClose();
}, 50);
});
ws3.on('message', function (msg) {
if (!ws3.connected) {
msg.type.should.eql('connect');
ws3.connected = true;
} else {
throw new Error('we shouldnt get a message here');
}
});
});
});
});
});
});
},
'test event with broadcast flag and to()': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, cl3 = client(port)
, io = create(cl1)
, messages = 0
, connections = 0
, disconnections = 0;
io.configure(function () {
io.set('close timeout', 0);
});
io.sockets.on('connection', function (socket) {
connections++;
if (connections == 1) {
socket.join('losers');
}
socket.on('trigger broadcast', function () {
socket.broadcast.to('losers').emit('victory');
});
socket.on('disconnect', function () {
disconnections++;
if (disconnections == 3) {
messages.should.eql(1);
cl1.end();
cl2.end();
cl3.end();
io.server.close();
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;
} else {
msg.should.eql({
type: 'event'
, name: 'victory'
, args: []
, endpoint: ''
});
messages++;
}
});
ws1.on('open', function () {
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;
} else {
throw new Error('This socket shouldnt get a message');
};
});
ws2.on('open', function () {
cl3.handshake(function (sid) {
var ws3 = websocket(cl3, sid);
ws3.on('open', function () {
ws3.packet({
type: 'event'
, name: 'trigger broadcast'
, endpoint: ''
});
setTimeout(function () {
ws1.finishClose();
ws2.finishClose();
ws3.finishClose();
}, 50);
});
ws3.on('message', function (msg) {
if (!ws3.connected) {
msg.type.should.eql('connect');
ws3.connected = true;
} else {
throw new Error('we shouldnt get a message here');
}
});
});
});
});
});
});
},
'test accessing handshake data from sockets': function (done) {
var cl = client(++ports)
, io = create(cl)
, ws;
io.sockets.on('connection', function (socket) {
(!!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/);
socket.on('disconnect', function () {
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 accessing the array of clients': function (done) {
var port = ++ports
, cl1 = client(port)
, cl2 = client(port)
, io = create(cl1)
, total = 2
, ws1, ws2;
io.sockets.on('connection', function (socket) {
socket.on('join ferrets', function () {
socket.join('ferrets');
socket.send('done');
});
});
function check() {
io.sockets.clients('ferrets').should.have.length(1);
io.sockets.clients('ferrets')[0].should.be.an.instanceof(sio.Socket);
io.sockets.clients('ferrets')[0].id.should.equal(ws1.sid);
io.sockets.clients().should.have.length(2);
io.sockets.clients()[0].should.be.an.instanceof(sio.Socket);
io.sockets.clients()[0].id.should.equal(ws1.sid);
io.sockets.clients()[1].should.be.an.instanceof(sio.Socket);
io.sockets.clients()[1].id.should.equal(ws2.sid);
ws1.finishClose();
ws2.finishClose();
cl1.end();
cl2.end();
io.server.close();
done();
};
cl1.handshake(function (sid) {
ws1 = websocket(cl1, sid);
ws1.sid = sid;
ws1.on('message', function (msg) {
if (!ws1.connected) {
msg.type.should.eql('connect');
ws1.connected = true;
ws1.packet({
type: 'event'
, name: 'join ferrets'
, endpoint: ''
});
} else {
cl2.handshake(function (sid) {
ws2 = websocket(cl2, sid);
ws2.sid = sid;
ws2.on('message', function (msg) {
if (!ws2.connected) {
msg.type.should.eql('connect');
ws2.connected = true;
check();
}
});
});
}
});
});
},
'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)
, calls = 0
, ws;
function close () {
cl.end();
io.server.close();
ws.finishClose();
done();
}
io.configure(function () {
io.set('heartbeat interval', .05);
io.set('heartbeat timeout', .05);
io.set('close timeout', 0);
});
io.of('/foo').on('connection', function (socket) {
socket.on('disconnect', function (reason) {
reason.should.equal('packet');
if (++calls == 2) close();
});
});
io.of('/bar').on('connection', function (socket) {
socket.on('disconnect', function (reason) {
reason.should.equal('socket end');
if (++calls == 2) close();
});
});
cl.handshake(function (sid) {
var messages = 0;
ws = websocket(cl, sid);
ws.on('open', function () {
ws.packet({
type: 'connect'
, endpoint: '/foo'
});
ws.packet({
type: 'connect'
, endpoint: '/bar'
});
});
ws.on('message', function (packet) {
if (packet.type == 'connect') {
if (++messages === 3) {
ws.packet({ type: 'disconnect', endpoint:'/foo' });
ws.finishClose();
}
}
});
});
},
'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;
}
});
});
},
'accessing the transport type': function (done) {
var cl = client(++ports)
, io = create(cl)
, ws;
io.sockets.on('connection', function (socket) {
socket.transport.should.equal('websocket');
socket.on('disconnect', function () {
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;
}
});
});
}
};