1

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?

Jolle
  • 1,336
  • 5
  • 24
  • 36

2 Answers2

0

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.

Jolle
  • 1,336
  • 5
  • 24
  • 36
0

This seems to be solved now with Heroku's session affinity https://socket.io/docs/v4/using-multiple-nodes/#passing-events-between-nodes

At least #worksforme on Heroku + Next.js (static serve) + socket.io (+ redis between servers)

Arno Teigseth
  • 199
  • 2
  • 10