Reputation: 2991
Is it possible to get rooms which socket is currently in, without calling
io.sockets.clients(roomName)
for every room name and looking for this socket in results
Upvotes: 30
Views: 64619
Reputation: 33
With socket.rooms
you will get a set of socketId and its rooms.
So you can convert it into array and then slice it to get only the rooms like this:
[...socket.rooms].slice(1, );
And then we can iterate through that array or access any room, for example:
[...socket.rooms].slice(1, )[1] // to get first room
Upvotes: 0
Reputation: 11486
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/
Upvotes: 13
Reputation: 4963
var rooms = Object.keys(io.sockets.adapter.sids[socket.id]);
// returns [socket.id, 'room-x'] or [socket.id, 'room-1', 'room-2', ..., 'room-x']
Upvotes: 13
Reputation: 790
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
Upvotes: 0
Reputation: 65
Socket.io v2.1.1
So make sure you aren't accessing the sockets rooms in the disconnect
event like I was, as they have already left the rooms by the time that event is triggered. If you want to do that try it in the disconnecting
event - https://github.com/socketio/socket.io/pull/2332/files
Then you can use any of the following:
Object.keys(socket.adapter.rooms)
Object.keys(socket.adapter.sids)
Object.keys(socket.rooms)
Upvotes: 2
Reputation: 307
Being sure that socket is in only one room at a time, my solution was:
var currentRoom = Object.keys(io.sockets.adapter.sids[socket.id]).filter(item => item!=socket.id);
Upvotes: 2
Reputation: 2898
Version 2.0.3
io.sockets.sockets[yourSocketID].rooms
That equal with
socket.rooms
Upvotes: 1
Reputation: 730
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.
Upvotes: 2
Reputation: 1324
socket.io 1.7.3 +
var currentRoom = socket.rooms[Object.keys(socket.rooms)[0]];//returns name of room
Upvotes: 0
Reputation: 1008
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
Upvotes: 4
Reputation: 14881
From the Socket.IO Room doc:
io.sockets.manager.roomClients[socket.id]
Upvotes: 12