socketio / socket.io-redis-streams-adapter

The Socket.IO adapter based on Redis Streams, allowing to broadcast events between several Socket.IO servers.
https://socket.io/docs/v4/redis-streams-adapter/
MIT License
29 stars 14 forks source link

Request support for clustered socket rooms #20

Open Timpan4 opened 7 months ago

Timpan4 commented 7 months ago

Socket.io has a concept of rooms for socket clients to join.

The Redis Adapter has support for clustered room emitting and room fetching via the allRooms() function. This function allows any socket.io server to fetch all rooms that are connected to the same redis pub/sub namespace, regardless of which socket.io server the client connected to.

This allows to emit specific events to specific rooms, regardless of where the room was created.

We were trying to change from using the original Redis Adapter to this new stream based adapter due to the support for Connection state recovery. But for now we need to continue to use the original.

darrachequesne commented 7 months ago

Hi! What do you mean by "clustered socket rooms"? Are you only missing the allRooms() method?

This allows to emit specific events to specific rooms, regardless of where the room was created.

This should already work. Isn't that the case for you?

Timpan4 commented 7 months ago

What i mean by "clustered socket rooms" is more or less server 1 can emit to a room that only exists on server 3 and vice versa.

We're using the allRooms() method to get a list of all available rooms across the cluster.

I have not tested if emitting to a room that lives on a different server compared to the one I'm emitting from

darrachequesne commented 7 months ago

My concern with the allRooms() of the Redis adapter is that it currently returns all rooms, including private ones (the ones named after the socket IDs), so it might return a lot of data.

That being said, I guess we could implement an allRooms() method for all adapters, which would exclude the private rooms and return the count of sockets for each room?

const rooms = await io.allRooms();

const count = rooms.get("room1");

@Timpan4 what do you think?

Timpan4 commented 7 months ago

Maybe something like this.

const rooms = await io.allRooms();

const socketsInRoom = rooms.get("room1");

That would mimic the Redis adapters functionality.

But excluding private ones would just be nice.