Is it possible to get rooms which socket is currently in, without calling
io.sockets.clients(roomName)
for every room name and looking for
When using a non-default adapter, such as socket.io-redis, socket.rooms
doesn't seem to do the trick. The way I managed to get the rooms for a specific client without looping was to use io.sockets.adapter.sids[socket.id]
, which returns the rooms as an object.
{ 'R-ZRgSf7h4wfPatcAAAC': true, ROOM: true, ROOM_2: true }
Note that this doesn't list sockets on other processes, though!
socket.io v1.3.7, socket.io-redis 1.0.0
You can save room in socket itself when it joins a room
// join room
socket.join(room);
// update socket's rooms
if (socket.rooms) {
socket.rooms.push(room);
} else {
socket.rooms = [room];
}
Later you can retrieve all rooms that the socket is in by simply
socket.rooms
From the Server API documentation:
socket.rooms (object)
A hash of strings identifying the rooms this client is in, indexed by room name.
https://socket.io/docs/server-api/#socket-rooms
In socket.io version 1+ the syntax is:
socket.rooms
var rooms = Object.keys(io.sockets.adapter.sids[socket.id]);
// returns [socket.id, 'room-x'] or [socket.id, 'room-1', 'room-2', ..., 'room-x']
With 3.x
Socket.rooms is Set
now, which means that values in the rooms may only occur once.
Structure example: Set(4) {"<socket ID>", "room1", "room2", "room3"}
io.on("connect", (socket) => {
console.log(socket.rooms); // Set { <socket.id> }
socket.join("room1");
console.log(socket.rooms); // Set { <socket.id>, "room1" }
});
To check for specific room:
socket.rooms.has("room1"); // true
More about Set and available methods: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
Migration Docs: https://socket.io/docs/migrating-from-2-x-to-3-0/
Version 1.7.3, socket.rooms
contains socket.id
, so remove it and get the list of rooms:
Object.keys(socket.rooms).filter(item => item!=socket.id);
In other version, you can print the socket
and find the rooms.