Socket.io 1.4 to 1.7.2 temporary fix for #2405: Server socket id doesn’t match client’s socket id

If you’re affected by the major change outlined by this reported issue here’s a temporary fix you may want to try to get things working again without having to change all of your own code:

find . -name "socket.io.js" -exec sed -i -e 's/socket\.id \= self\.engine\.id;/socket\.id \= socket\.nsp \+ "\#" \+ self\.engine\.id;/' {} \;
find . -name "socket.io.js" -exec sed -i -e 's/this\.nsps\[nsp\]\.id \= this\.engine\.id;/this\.nsps\[nsp\]\.id \= nsp \+ "\#" \+ this\.engine\.id;/' {} \;
find . -name "socket.io.js.map" -exec sed -i -e 's/socket\.id \= self\.engine\.id;/socket\.id \= socket\.nsp \+ "\#" \+ self\.engine\.id;/' {} \;
find . -name "socket.io.js.map" -exec sed -i -e 's/this\.nsps\[nsp\]\.id \= this\.engine\.id;/this\.nsps\[nsp\]\.id \= nsp \+ "\#" \+ this\.engine\.id;/' {} \;
find . -name "socket.io.slim.js.map" -exec sed -i -e 's/socket\.id \= self\.engine\.id;/socket\.id \= socket\.nsp \+ "\#" \+ self\.engine\.id;/' {} \;
find . -name "socket.io.slim.js.map" -exec sed -i -e 's/this\.nsps\[nsp\]\.id \= this\.engine\.id;/this\.nsps\[nsp\]\.id \= nsp \+ "\#" \+ this\.engine\.id;/' {} \;
find . -name "socket.io.min.js" -exec sed -i -e 's/n\.id\=o\.engine\.id/n\.id\=n\.nsp\+"\#"\+o\.engine\.id/' {} \;
find . -name "socket.io.min.js" -exec sed -i -e 's/this\.nsps\[t\]\.id\=this\.engine\.id/this\.nsps\[t\]\.id\=t\+"\#"\+this\.engine\.id/' {} \;
find . -name "socket.io.slim.min.js" -exec sed -i -e 's/n\.id\=o\.engine\.id/n\.id\=n\.nsp\+"\#"\+o\.engine\.id/' {} \;
find . -name "socket.io.slim.min.js" -exec sed -i -e 's/this\.nsps\[t\]\.id\=this\.engine\.id/this\.nsps\[t\]\.id\=t\+"\#"\+this\.engine\.id/' {} \;
find . -name "manager.js" -exec sed -i -e 's/socket\.id \= self\.engine\.id;/socket\.id \= socket\.nsp \+ "\#" \+ self\.engine\.id;/' {} \;

Running this as a bash script in the root folder of your projects that depend on socket.io-client will replace all instances in the socket.io-client code to use the naming convention prior to v1.4 (and thus maintain consistency across client and server): the namespace followed by # and then the engine id.

If you run the bash script and want to undo the above changes, you’ll have to reverse the sed regular expressions and rerun the script.

*     *     *

You may enjoy playing a game at GameSlush.com because it also uses socket.io.

Socket.io 1.2.0: Handling global authorization events when client connects to a custom namespace

The documentation on socket.io’s page and its GitHub page are inconsistent (namely due to the latter being out of date, but contains information not covered by the former). A problem arises when using global authorization middleware on the server, having a client trying to connect to a custom namespace, and having the server deny access to the connecting client by passing an error to next() in the middleware.

Sample server authorization middleware code that denies access globally to all incoming connections:

io.use(function(socket, next) {
  next(new Error('not authorized'));
});

Sample client connecting code with error handler:

var socket = require('socket.io-client')('http://localhost/customnamespace');

socket.on('error', function(err) {
  console.log(err); // 'not authorized' not output, 
                    // since this is a '/customnamespace' event handler
});

The client needs to handle both the events coming from the global namespace and the custom namespace, otherwise the socket connection seemingly hangs on the client side as it receives no feedback from the custom namespace event handlers. None of the socket.io documentation seems to cover this shortcoming.

You can simply get any namespace socket from the socket Manager by calling Manager.socket([namespace]). To get the socket Manager from any socket, simply reference the ‘io’ property of the socket object. From there we would use ‘/’ to get the global namespace socket.

Here’s the proposed workaround that continues the sample client code above:

var socket = require('socket.io-client')('http://localhost/customnamespace');
var manager = socket.io;
var socketGlobalNs = manager.socket('/');

socket.on('error', function(err) {
  console.log(err); // 'not authorized' not output, 
});

socketGlobalNs.on('error', function(err) {
  console.log(err); // This will output 'not authorized'
});