Question

I am trying to connect from one server (acting as a master) to another 2 servers (acting as slaves, both having the same code) using socket.io and socket.io-client node modules, using the following code:

var ioClient = require('socket.io-client');
var hosts = require('./hosts');
var x = {}
for (var i in hosts.get) {
  var name = 'ns' + i;
  x[name] = ioClient.connect(hosts.get[i].url, { 'force new connection':true });
  x[name].on('connect', function() {
    console.log(x[name].socket.options.host + ' connected')
  });
}

As you can see, I am trying to connect to X different servers (defined in the file hosts.js) and store each socket in an object.

The problem is, despite I am able to connect, all the sockets seem to come from the last host , so I end up like this:

host2.pc.gg.edu connected
host2.pc.gg.edu connected

When the expected value is:

host1.pc.gg.edu connected
host2.pc.gg.edu connected

I've tried disconnecting host1, and then the output end up being this:

host2.pc.gg.edu connected

So I asume the problem is the socket not establishing correctly the field "options.host"

The funny part comes when I do the same code, but instead of using variable keys in the object, using eval:

var ioClient = require('socket.io-client');
var hosts = require('./hosts');
var x = {};
for (var i in hosts.get) {
    eval('x.ns' + i + '= ioClient.connect(hosts.get[' + i + '].url, { "force new connection":true });x.ns' + i + '.on("connect", function() {console.log(x.ns' + i + '.socket.options.host + " connected")});');
}

Amazingly, this works, and I cannot tell the difference between the two codes. I am sure it's probably more a JavaScript error rather than a socket.io error, but I'm not able to find a solution after hours of trying...

Thank you very much

Was it helpful?

Solution

The sockets are connecting just fine, the problem is with the on connect callback. More specifically, by the time the callback is actually invoked, the for loop will have already completed, and the variable i and subsequently the variable name, will be pointing to the last element. You can get around this by creating a closure around each iteration of the loop, thus preserving the current value of i within the scope of the callback.

for (var i in hosts.get) {
    var name = 'ns' + i;
    (function (name) {
        x[name] = ioClient.connect(hosts.get[i].url, { 'force new connection':true });
        x[name].on('connect', function () {
            console.log(x[name].socket.options.host + ' connected')
        });
    })(name);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top