Migrating to Socket.IO 1.0
There are a few things not covered in the official guide that I had to figure out on my own. Here is an example of the changes required for a mock application using namespaces, rooms, query strings, and a reverse proxy.
Client #
var socket = io.connect('//example.com/mynamespace?mynumber=123', {
'force new connection': true,
'resource': 'path/to/socket.io'});
socket.on('connect_failed', function(data)
{
console.log('connect_failed');
});
socket.on('connecting', function(data)
{
console.log('connecting');
});
socket.on('disconnect', function(data)
{
console.log('disconnect');
});
socket.on('error', function(reason)
{
console.log('error');
});
socket.on('reconnect_failed', function(data)
{
console.log('reconnect_failed');
});
socket.on('reconnect', function(data)
{
console.log('reconnect');
});
socket.on('reconnecting', function(data)
{
console.log('reconnecting');
});
socket.socket.disconnect();
Becomes
var socket = io(window.location.protocol + '//example.com/mynamespace?mynumber=123', {
'multiplex': false,
'path': '/path/to/socket.io'});
socket.on('disconnect', function(data)
{
console.log('disconnect');
});
socket.disconnect();
Things to note:
- You can no longer use a protocol relative url for connection.
- There’s an extra
/
in the path. - You no longer get detailed reconnection events. Instead, you just assume that it’s attempting to reconnect when you get a
disconnect
event.
Server #
var io = socketio.listen(server);
io.configure('development', function()
{
io.set('browser client', false);
io.set('log level', 3);
});
io.set('authorization', function(data, accept)
{
var query = data.query;
data.myNumber = query.mynumber;
accept(null, true);
});
io.of('mynamespace').addListener('connection', function(socket)
{
var myNumber = socket.handshake.myNumber;
console.log(myNumber, 'connected');
socket.join('myroom');
var roomClients = io.of('mynamespace').clients('myroom');
for(var i = 0; i < roomClients.length; i++)
{
console.log(roomClients[i].handshake.myNumber, 'is in myroom');
}
}
Becomes
var io = socketio.listen(server);
var socketData = {};
if(!process.env.NODE_ENV)
{
io.attach(server, {
'serveClient': false
});
});
io.use(function(socket, next)
{
var query = socket.request._query;
socketData[socket.id] = {
myNumber: query.mynumber
};
next();
});
io.of('mynamespace').addListener('connection', function(socket)
{
var myNumber = socketData[socket.id].myNumber;
console.log(myNumber, 'connected');
var roomClients = io.of('mynamespace').adapter.rooms['myroom'];
for(var socketId in roomClients)
{
if(roomClients.hasOwnProperty(socketId))
{
console.log(io.of('mynamespace').connected[socketId], 'is in myroom');
}
}
}
Things to note:
- The
io.configure
method is gone. - Socket.IO 1.0 uses the debug module, so you set the log level when calling Node.js.
- There are methods on the server object for each configuration option, but I found that they didn’t work, so I had to pass all the options into the
attach
call. - You can no longer store data on the
handshake
object. - For no apparent reason, you have to access the query parameters through the
socket.request._query
property. - Also for no apparent reason, you can’t get a list of the sockets connected to a room. You have to get socket ids from
namespace.adapter.rooms
property, then look up the actual socket in thenamespace.connected
property.
nginx #
The last thing I had to do was reconfigure my reverse proxy, which happens to be nginx. Because Socket.IO 1.0 uses a different handshake that requires more requests to be sent, I had to increase the allowed request rate for the connection to be established in a reasonable amount of time.
limit_req_zone $binary_remote_addr zone=nodejs:10m rate=1r/s;
Becomes
limit_req_zone $binary_remote_addr zone=nodejs:10m rate=8r/s;