elad / node-cluster-socket.io

Writeup on how to make node.js cluster and socket.io play nice
421 stars 63 forks source link

Duplicated messages #9

Open michelem09 opened 9 years ago

michelem09 commented 9 years ago

I'm looking for a way to handle the duplicated messages I got when I emit a message with this code, any idea?

tjomych commented 8 years ago

I have the same problem. Any solution?

peterfrankjohnson commented 8 years ago

I had this problem when using this solution on Heroku because they have a load balancer in front of the server which causes problems.

I modifed the code to use the connection._server.connectionKey string as an index and pull the port number and use that as the index, this code may work for you if you are behind a load balancer and the setup is similar to Heroku.

var worker_index = function(ip6, len) {
    var components = ip6.split(":");
    ip = components[components.length - 1];

    var s = '';
    for (var i = 0, _len = ip.length; i < _len; i++) {
        if (ip[i] !== '.') {
            s += ip[i];
        }
    }

    return Number(s) % len;
};

// Create the outside facing server listening on our port.
var server = net.createServer({ pauseOnConnect: true }, function(connection) {
    // We received a connection and need to pass it to the appropriate
    // worker. Get the worker for this connection's source IP and pass
    // it the connection.
    var worker = workers[worker_index(connection.server._connectionKey, num_processes)];
    worker.send('sticky-session:connection', connection);
}).listen(port);
elad commented 8 years ago

Folks who filed #7 and #15 might be interested in this solution.

davidolen commented 7 years ago

@elad, Thank you for your smart work on this guide.

Regarding issues (#7 and #15), I just tried the above idea and found that the port at the end of connection.server._connectionKey appear to be always the same, which is the listening port (e.g., 9000) of the master process. So, I guess connection.server._connectionKey cannot be used as the worker_index. Not sure how Peter made it work. Probably I missed something. @ peterfrankjohnson, please correct me if I'm wrong.

I also tried to use connection.remotePort as the worker_index, and of course as expected it didn't work :-)

https is almost always a requirement. I agreed with you that using reverse proxy (nginx) is the right choice for the most part. At least, we don't have another choice at this moment :-)

I know you probably are really busy now, but if possible could you please still share you idea on this problem since it has become a blocking issue.

Thanks again for sharing your ideas and the contribution you already made!