Socket.IO IPv6 (January 2013 Edition)

I need to use Socket.IO and its client to connect between two Node.js servers over an IPv6 network.

One year ago, this didn't seem possible due to the address parsing with the client. Now it seems that at least one person has gotten it working.

So, I tried some simple test code on the server:

var io = require('socket.io').listen(8124, '::1');

And, on the client:

io.connect('http://[::1]:8124');

This fails. (No error is output, which I am investigating now. I assume this is a bug in the crash handler I'm using from winston.)

I've also noticed that if I go to http://[::1]:8124/ in Chrome, I don't get the usual, "Welcome to socket.io.", debugging message. Strangely enough, if I go to http://127.0.0.1:8124/, I do get that message, despite telling the server to only listen on ::1.

As of version 0.9.11 of Socket.IO, is it possible to use IPv6? If so, how?

Try

var io = require('socket.io').listen(require('http').createServer().listen(8124, '::1'));

or (to get the debug message):

var server = require('http').createServer().on('request', function (req, res) {
    res.writeHead(200);
    res.end('Welcome to socket.io.');
}).listen(8124, '::1');
var io = require('socket.io').listen(server);

I tested it with curl (curl -g http://[::1]:8124/) and nodejs:

require("http").get({hostname:"::1", port:8124,path:"/"}, function(res) {
    console.log("Got response: " + res.statusCode);
    res.on("data",function(chunk) {
        console.log("BODY: " + chunk);
    });
}).on("error", function(e) {
    console.log("Got error: " + e.message);
});

Using "real" hostnames works with the client:

require('socket.io-client').connect('http://ip6-localhost:8124/');

my /etc/hosts contains the entry ::1 ip6-localhost, so if you have hostnames which point to IPv6 addresses only, this should work. (If the first connect didn't work it does not fallback to another address, so using localhost as name it didn't fallback to IPv6 from IPv4).

Sadly it looks like the nodejs url module (at least the version 0.6.19 in debian) doesn't support literal addresses, and therefore neither does the xmlhttprequest module:

console.log(require('url').parse('http://[::1]:8124/'));

The socket.io-client module doesn't support literal addresses either, but you could fool it like this:

require('socket.io-client').connect('http://blank:8124/', {host:'[::1]'});

This will use XMLHTTPRequest as backend though, so it still doesn't work with nodejs (perhaps it works with a "real" XMLHTTPRequest object in a browser, or a newer nodejs version).

Update: more recent node versions (tried v0.9.6-16-g9668df8) support literal ipv6 addresses in the url parser, and therefore in xmlhttprequest.