2

I am having problems getting the sticky-sessions socket.io module to work properly with even a simple example. Following the very minimal example given in the readme (https://github.com/indutny/sticky-session), I am just trying to get this example to work:

var cluster = require('cluster');
var sticky = require('sticky-session');
var http   = require('http');

if (cluster.isMaster) {
  for (var i = 0; i < 4; i++) {
    cluster.fork();
  }

  Object.keys(cluster.workers).forEach(function(id) {
    console.log("Worker running with ID : " + 
      cluster.workers[id].process.pid);
  });
}

if (cluster.isWorker) {
  var anotherServer = http.createServer(function(req, res) {
    res.end('hello world!');
  });
  anotherServer.listen(3000);
  console.log('http server on 3000');
}

sticky(function() {
  var io = require('socket.io')();

  var server = http.createServer(function(req, res) {
    res.end('socket.io');
  });

  io.listen(server);

  io.on('connection', function onConnect(socket) {
    console.log('someone connected.');

    socket.on('sync', sync);
    socket.on('send', send);

    function sync(id) {
      socket.join(id);
      console.log('someone joined ' + id);
    }

    function send(id, msg) {
      io.sockets.in(id).emit(msg);
      console.log('someone sent ' + msg + ' to ' + id);
    }
  });

  return server;
}).listen(3001, function() {
  console.log('socket.io server on 3001')
});

and a simple client:

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

socket.on('connect', function() { 
  console.log('connected')
  socket.emit('sync', 'secret') 
});

The workers start up fine. The http servers work fine. But when the client connects, the console logs 'someone connected' and nothing more. The client never fires the on connect event, so I think the upgrade/handshake is failing or something. If anyone can spot what I am doing wrong that would help alot.

Thanks!

jordyyy
  • 54
  • 1
  • 7
  • ever resolve this? I just get issues with the client reconnecting constantly – Horse Mar 06 '15 at 08:27
  • Essentially sticky-session isn't maintained at all. I did not want to use redis, because i wanted everything to be simple, but in the end i had to. The redis adapter is extremely easy to use, and you don't have to configure anything. Just install redis and hook everything up. There was one last thing I had to do in order to get this to work on cluster: I HAD to specify, on both client and server, transports:web sockets. WS had to be the first (ws, then polling) or the only option. After doing these two things everything works perfectly. I can update my answer with examples if needed. – jordyyy Mar 07 '15 at 19:02
  • thanks for the response, yes please that would be really helpful :) – Horse Mar 09 '15 at 10:46

2 Answers2

3

@jordyyy : I was facing same issue after googling I have fond answer. Socket.Io handshaking task complete in more than one request and when you will run on sticky session it means you are using multiple process according to your core.

So handshaking request will distribute on different different process and they can't talk.(not IPC) (They are child process) and most of time connection will be failed/lost.(connection-disconnect event occurs frequently )

So what is solution ? Solution is socketio-sticky-session

Socketio-sticky-session, manage connection on IP based. So when you will request by any client then it will maintain ip address with respect process/worker. So further request will be forward to same process/worker and your connection properly stabilized.

And When you will use redies adapter then you can actually maintain socket connection data b/w all processes/workers.

For more information https://github.com/elad/node-cluster-socket.io (you need some patch on worker_index method, if your server is supporting IPv6)

Just knowledge bytes. :) :)

One more thing, you don't need to fork process. It will be done by sticky session.

Manish Trivedi
  • 3,481
  • 5
  • 23
  • 29
  • Thanks for the input. I am happy to take suggestions but the question was about a specific module, and I don't really think use another module is a good answer – jordyyy Dec 26 '15 at 17:15
  • @jordyyy : Your welcome :) When you will open this module lib. Its just a one file script. Same as you had wrote, except connection handling :) – Manish Trivedi Dec 28 '15 at 04:14
0

This was super old and wasn't really answered when i needed it, but my solution was to drop this bad module and any other super confusing module and just use pub/sub with redis adapter. The only other step was to force transports to websockets, and if that bothers anyone then use something else. For my purposes my solution was simple, readable, didn't mess with the 'typical' socket.io api, and best of all it worked extremely well.

jordyyy
  • 54
  • 1
  • 7