socket.io-redis-adapter icon indicating copy to clipboard operation
socket.io-redis-adapter copied to clipboard

How to update redis URL on fly

Open benoitDD opened this issue 5 years ago • 2 comments

Hello,

How can I update redis URL on fly ?

I use: node 10.16.0 express 4.17.1 socket.io 2.3.0 socket.io-redis 5.2.0 socket.io-client 2.3.0

I try to replace with a new Adaptater and set it to socket server: Server

var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var redisAdapter = require('socket.io-redis');

//the old adaptater.
io.adapter(redisAdapter({ host: 'localhost', port: 6379 }));

http.listen(3000, () => {
   console.log('listening on *:3000');

   setInterval(() =>{
      io.emit('bar')
   }, 1000)

   setTimeout(() => {
      //the REDIS URL is updated, so I must update the Adaptater with the new URL of REDIS.
      io.adapter(redisAdapter({ host: 'localhost', port: 6378 }));
   }, 10000)
})

The redis instances in port 6378 and 6379 work.

My issue: after updated the REDIS URL, the clients socket.io (socket.io-client) don't receive the event bar (and any other events !)

Before to update the REDIS URL the clients had received the event bar.

Client

var io = require('socket.io-client')
var socket = io.connect('http://localhost:3000')
socket.on('bar', () => console.log('receive'))

After the update of REDIS URL, to receive this event, the clients socket.io must to disconnect and reconnect. (it's bad!)

benoitDD avatar Jul 04 '20 12:07 benoitDD

Hi! You're right, hot-reloading an adapter is not currently supported. The rooms and sids objects, which store the relationships between sockets and rooms, are lost when using the new adapter. A quick workaround:

setTimeout(() => {
  const rooms = io.of('/').adapter.rooms;
  const sids = io.of('/').adapter.sids;

  //the REDIS URL is updated, so I must update the Adaptater with the new URL of REDIS.
  io.adapter(redisAdapter({ host: 'localhost', port: 6378 }));

  io.of('/').adapter.rooms = rooms;
  io.of('/').adapter.sids = sids;
}, 10000);

I'm not sure this is a common use case though.

darrachequesne avatar Jul 09 '20 10:07 darrachequesne

I'm currently investigating an issue where I have a Sentinel Redis setup that my socket-io server is connecting to using this adapter.

In the situation that the sentinel master is 'destroyed', a slave is promoted to be the new 'master'. The adapter seems to never successfully connect to the new master, and starts throwing different timeout errors. e.g. Error: timeout reached while waiting for clients response.

I'll get a dev environment setup and investigate if i can connect to the new master. This seems like a good solution if all else fails. Any other pointers in the right direction would be greatly appreciated, thank you @darrachequesne!

JordanPawlett avatar Aug 26 '20 16:08 JordanPawlett