socket.io-redis-adapter
socket.io-redis-adapter copied to clipboard
dynamic subscription mode breaks socket.emit()
When using the sharded adapter with subscriptionMode: "dynamic"
, messages sent to the socket's private room via socket.emit()
get lost without any warning or error.
It happens because in this check, such messages look just like any other single-room broadcasts, so useDynamicChannel
ends up being true
but private rooms are excluded here so there are no subscribers.
I can see a couple of possible solutions here, but none is ideal:
- Attempt to identify the channel is private during emit, and set
useDynamicChannel
tofalse
in such case. I made an attempt on this in #525 but it seems somewhat tricky. - Clearly document that
socket.emit()
won't work in this mode. - Remove the exception for private rooms and subscribe to them as well.
- Combination of 2 and 3 - add an option for subscribing to private rooms and document
socket.emit()
won't work without it.
Upon further consideration, I think, regardless of this issue, it makes sense to have an option for creating separate channels for private rooms.
In our scenario, we have ~1k clients connected to ~10 servers, all communication is 1:1, and the connections stay open for a long time. Using separate channels significantly lowers the overall redis bandwidth, and the subscription/unsubscription impact shouldn't be significant. We could create our own "public" channel for each client, but using the existing ones seems like the cleanest option.
I implemented this, along with the previous fix, in #526. We're already running this in production, and it reduced the overall redis load by 50 - 60 % in our setup.
Hi! I could indeed reproduce the issue, thanks for reporting this.
This happens when calling io.to(someSocketId).emit("hello");
(which is also what happens with a RemoteSocket, under the hood). Classic socket.emit()
's are not affected though.
Classic socket.emit()'s are not affected though.
By this, you mean local emits? If yes, that's right, it only affects emits on remote sockets.