My server codes use io.to(socketId).emit('xxx');
to a message to a particular socket, refer to https://socket.io/docs/emit-cheatsheet/
But when the connection is bad and the client disconnects and connects again, socketId changes and io.to(socketId).emit('xxx');
then fails. So how do I implement a re-emit method to handle the reconnection ?
My question is kind of opposite to this one, socket.io stop re-emitting event after x seconds/first failed attempt to get a response, from it I learn that socket.io client can re-emit when it reconnects. But the server code seems to lack that support.
--- update ---
As the comment said I show here "the code context where you're saving the socketId value that gets stale."
First, each user has a unique id in our system, when socket connects the client will send a login message so I save the userId and socketId pair. When I get disconnect event I clear that info.
Second, the user will get messages through redis pubsub (from other service), and I will send that message to the client throught the socketid I record. So when socket connects I will subscribe a channel identified by userid and unsubscribe it in disconnect event.
Third, my problem happens when I get redis pub event while socketId value gets stale. Actually the value of socketid is the latest one but the socket may fail to send the message.
io.on('connection', async function (socket) {
socket.on('login', async function (user_id, fn) {
...
await redis
.multi()
.hset('websocket:socket_user', socket.id, user_id)
.hset(
`websocket:${user_id}`,
'socketid',
socket.id
)
.exec()
await sub.subscribe(user_id)
...
}
socket.on('disconnect', async function (reason) {
let user_id = await redis.hget('websocket:socket_user', socket.id)
await redis.del(`websocket:${user_id}`)
sub.unsubscribe(user_id)
...
}
//Here is what problem happens when socket is trying to reconnect
//while I got redis pub message
sub.on('message', async function (channel, message) {
let socketid = await redis.hget(`websocket:${channel}`, 'socketid')
if (!socketid) {
return
}
//so now I assume the socketid is valid,
//but it turns out clients still complain they didn't receive message
io.to(socketid).emit('msg', message) //When it fails how do I re-emit?
})