node.jsherokusticky-session

Sticky Session on Heroku


We have have a NodeJS application running with SocketIO and clustering on heroku. To get SocketIO working we use the redis-adapter like discussed here: https://socket.io/docs/using-multiple-nodes/.

Then we've implemented sticky sessions like shown in the sticky session documentation here: https://github.com/elad/node-cluster-socket.io.

Turns out that when we deploy to Heroku, the connection.remoteAddress in:

// 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 index = worker_index(connection.remoteAddress, num_processes);
    var worker = workers[index];
    worker.send('sticky-session:connection', connection);
}).listen(port);

is actually the IP address of some heroku routing server and NOT the client IP. I've seen that the request header "x-forwarded-for" could be used to get the client IP, but when we pause the connection in this way, we don't even have the headers yet?


Solution

  • We searched all over for a solution, but apparently there's no good solutions.

    Here are some of the better suggestions:

    https://github.com/indutny/sticky-session/issues/6

    https://github.com/indutny/sticky-session/pull/45

    None of them seemed good performance wise and therefore we ended up changing SocketIO communication to Websockets only. This eliminates the need for sticky sessions all together.