42

after progress on the question how to create socket.io multicast groups, I found making rooms a great way to do what I needed.

However, it would be great to know about all the rooms, without an extra data-structure.

Is it possible to get a list of all rooms on the server from the server socket?

Community
  • 1
  • 1
pyramation
  • 1,631
  • 4
  • 22
  • 35

17 Answers17

57

The short answer:

io.sockets.adapter.rooms

I analysed io:

I got the following output:

{ server: 
   { stack: 
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ],
     connections: 3,
     allowHalfOpen: true,
     watcher: { host: [Circular], callback: [Function] },
     _events: 
      { request: [Function],
        connection: [Function: connectionListener],
        listening: [Object],
        upgrade: [Object] },
     httpAllowHalfOpen: false,
     cache: {},
     settings: { home: '/', env: 'development', hints: true },
     redirects: {},
     isCallbacks: {},
     _locals: { settings: [Object], app: [Circular] },
     dynamicViewHelpers: {},
     errorHandlers: [],
     route: '/',
     routes: 
      { app: [Circular],
        routes: [Object],
        params: {},
        _params: [],
        middleware: [Function] },
     router: [Getter],
     __usedRouter: true,
     type: 'tcp4',
     fd: 7 },
  namespaces: 
   { '': 
      { manager: [Circular],
        name: '',
        sockets: [Object],
        auth: false,
        flags: [Object],
        _events: [Object] } },
  sockets: 
   { manager: [Circular],
     name: '',
     sockets: { '210837319844898486': [Object] },
     auth: false,
     flags: { endpoint: '', exceptions: [] },
     _events: { connection: [Function] } },
  settings: 
   { origins: '*:*',
     log: true,
     store: 
      { options: undefined,
        clients: [Object],
        manager: [Circular] },
     logger: { colors: true, level: 1 },
     heartbeats: true,
     resource: '/socket.io',
     transports: 
      [ 'websocket',
        'htmlfile',
        'xhr-polling',
        'jsonp-polling' ],
     authorization: [Function],
     'log level': 1,
     'close timeout': 25,
     'heartbeat timeout': 15,
     'heartbeat interval': 20,
     'polling duration': 20,
     'flash policy server': true,
     'flash policy port': 843,
     'destroy upgrade': true,
     'browser client': true,
     'browser client minification': false,
     'browser client etag': false,
     'browser client handler': false,
     'client store expiration': 15 },
  handshaken: 
   { '210837319844898486': 
      { headers: [Object],
        address: [Object],
        time: 'Mon Jul 18 2011 00:53:27 GMT+0200 (CEST)',
        xdomain: false,
        secure: undefined,
        PHPSESSID: '7qo6cht3q0rskhfes4eesb2d05' } },
  connected: { '210837319844898486': true },
  open: { '210837319844898486': true },
  closed: {},
  closedA: [],
  rooms: 
   { '': [ '210837319844898486' ],
     '/public-alfred': [ '210837319844898486' ] },
  roomClients: { '210837319844898486': [ '': true, '/public-alfred': true ] },
  oldListeners: [ [Function] ],
  _events: 
   { 'set:origins': [Function],
     'set:flash policy port': [Function],
     'set:transports': [Function] } }

after joining room "public-alfred" from a single client io.sockets.adapter.rooms contained:

 { '': [ '210837319844898486' ],
         '/public-alfred': [ '210837319844898486' ] }
nole
  • 563
  • 1
  • 5
  • 16
Alfred
  • 60,935
  • 33
  • 147
  • 186
  • 6
    Or even simpler, `io.rooms` works as `io.sockets.manager` is a circular reference. They will give you the same thing, just `io.rooms` is less verbose. – ADAM Aug 25 '13 at 09:33
  • 2
    I don't think this works with socket.io version 1.0. Maybe? `io.nsps['/'].adapter.rooms` – Arnaldo Capo Jun 05 '14 at 16:14
  • 2
    Alfred, i edited the answer for both API version, there are potential reader still using 9.x like me :) – Marwen Trabelsi Aug 03 '14 at 22:31
  • 3
    simple `socket.rooms` does the trick nowadays.. gotta love progress ;) – Dmitry Matveev Nov 25 '15 at 01:15
  • Heads up: this is changing in socket.io 1.4.x – mikermcneil Jan 07 '16 at 04:55
  • 4
    @Alfred, I am using version 1.4.x. How do I get the room names for each room within `io.sockets.adapters.rooms`? When I create a room and join, I do allot it a name like `socket.join('someRoom')`, but when I use `io.sockets.adapters.rooms`, I get a reference like `/#4Ps4Ql-bx2R3qFH6AAAC`. How do I get the corresponding name? – Sajib Acharya Jan 24 '16 at 18:01
  • Can we update this answer for socket.io 3.x.x ? as this no longer works – Krzysztof Krzeszewski Nov 13 '20 at 10:46
20

As everyone said, in a new version of socket.io (1.x) the rooms can be found at:

    io.sockets.adapter.rooms

This will return something like:

{ 
    'qNADgg3CCxESDLm5AAAA': [ 'qNADgg3CCxESDLm5AAAA': true ],
    'myRoom': [ 'qNADgg3CCxESDLm5AAAA': true,
                '0rCX3v4pufWvQ6uwAAAB': true,
                'iH0wJHGh-qKPRd2RAAAC': true ],  
    '0rCX3v4pufWvQ6uwAAAB': [ '0rCX3v4pufWvQ6uwAAAB': true ],  
    'iH0wJHGh-qKPRd2RAAAC': [ 'iH0wJHGh-qKPRd2RAAAC': true ] 
}

The only room that I want to get is 'myRoom', so I wrote the following function for doing that:

function findRooms() {
    var availableRooms = [];
    var rooms = io.sockets.adapter.rooms;
    if (rooms) {
        for (var room in rooms) {
            if (!rooms[room].hasOwnProperty(room)) {
                availableRooms.push(room);
            }
        }
    }
    return availableRooms;
}

This was kind of confusing for me, hope this helps!

gastonmancini
  • 1,102
  • 8
  • 19
  • Your `findRooms()` function keeps returning all rooms to me as all items in that array have the property `room`. I'm on `socket.io v1.4.5` – Pherrymason Jul 04 '16 at 14:52
17

In a new version of socket.io (1.x), io.sockets.manager.rooms will cause an error. You should use io.sockets.adapter.rooms instead.

Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
6

In socketIO version 2.2.0,

  • io.sockets.manager does not exist anymore

You can get all sockets in a specific room using followings 3.

socket.adapter.rooms;
io.sockets.adapter.rooms
io.sockets.adapter.sids

If you are using namespace you should use socket.adapter.rooms to get the room lists.

{ '/userSocket#oXorUiql1GF68dbTAAAB':
   Room {
     sockets: { '/userSocket#oXorUiql1GF68dbTAAAB': true },
     length: 1 
     },
  roomOneName:
   Room {
     sockets: { '/userSocket#oXorUiql1GF68dbTAAAB': true },
     length: 1 
     },
  roomTwoName:
   Room {
     sockets: { '/userSocket#oXorUiql1GF68dbTAAAB': true },
     length: 1 
   } 
}
Community
  • 1
  • 1
Md Alamin
  • 1,084
  • 11
  • 19
3

in case you are using

socket.io 2.1.0

and chanced upon this.

in 2.1.0, all the rooms in the server are located in the variable io.sockets.adapter.rooms

//Use Example//

sockets.on('getRooms', function() {
    sockets.emit('rooms', io.sockets.adapter.rooms);
});

You will get the following results.

{ xqfGuWYkKzT9hGgGAAAB: Room { sockets: { xqfGuWYkKzT9hGgGAAAB: true }, length: 1 }, '0Ak9nTjme7bLsD8NAAAC': Room { sockets: { '0Ak9nTjme7bLsD8NAAAC': true }, length: 1 } }

Someone Special
  • 12,479
  • 7
  • 45
  • 76
3
Object.keys(io.sockets.adapter.rooms)

use this to get all rooms.

Ahmad Ali
  • 148
  • 2
  • 10
2

If io.sockets.adapter is undefined..

I'm using socket.io 1.7.1 (Server).

It seems io.of("......").sockets.adapter is undefined on that version of socket.io. So I used io.adapter.rooms instead and it works.

2

According to the documentation of Socket.io-v3.x, to get all current rooms created, you just simply do socket.rooms

io.on('connection', socket => {

  console.log(socket.rooms);
  socket.on('disconnect', () => {
    // socket.rooms.size === 0
  });
});

and it return like this

Set(2) {
  '_y_xQeeF6PpFiPQqAAFC',
  '6113cb71359644408895afcf6112df3c76981e3f88bc5c08'
} 
Dharman
  • 30,962
  • 25
  • 85
  • 135
Marvin
  • 647
  • 7
  • 15
1

in Socketio 2.0

to get rooms use

Object.keys(socket.adapter.rooms);

to get the room name

Object.keys(socket.adapter.rooms)[1];
jay ram
  • 61
  • 1
  • 4
1

Filtering out the 'real' rooms can be done like this:

var realRooms = Object.keys(io.sockets.adapter.rooms).reduce((filtered, key) => {
    if(!io.sockets.adapter.rooms[key].sockets.hasOwnProperty(key)) filtered.push(key);
    return filtered;
}, []);
Sam
  • 5,375
  • 2
  • 45
  • 54
1

I was able to find them using socket._events on an open connection.

io.sockets.on('connection', function(socket){
  socket.on('ping', function(data){
    console.log(socket._events);
  });
});

Output:

{
  ping: [Function],
  disconnect: [Function]
}
  • 1
    I believe the OP asked how to find rooms. This would be events. Still helpful on certain occasions but just not related to this question. – Chance Chapman Jul 23 '15 at 22:49
1

on v4 proceed like this:

Array.from(io.adapter.rooms.entries())

It will return an array with the keys (roomIds) and values (socketIds), same structure as Object.entries():

[
  [roomId],[Set(2) {"socketId1","socketId2"}],
  [roomId2], [Set(3) {"socketId3","socketId4","socketId5"}],
]
Psartek
  • 481
  • 3
  • 9
0

I don't have enough reputation to post my comment to the original question, but in addition, if you want to list all the rooms in a namespace, it should be coded like this:

var nsp = io.of('/my-nsp');

var rooms = nsp.adapter.rooms;

This would help so that if a client join a room by:

socket.join('my-room');

You should be able to see your room name when you do console.log(rooms);

I just want to answer an unanswered comment above as I ran into the same issue after I saw mismatched room names.

conchimnon
  • 41
  • 1
  • 1
  • 10
0
function ActiveRooms(){
        var activeRooms = [];
        Object.keys(io.sockets.adapter.rooms).forEach(room=>{
            var isRoom = true;
            Object.keys(io.sockets.adapter.sids).forEach(id=>{
                isRoom = (id === room)? false: isRoom;
            });
            if(isRoom)activeRooms.push(room);
        });
        return activeRooms;}
Jay Stratemeyer
  • 506
  • 4
  • 6
0

For socket v4. This works:

io.sockets.adapter.rooms.get("id of the room")
olawalejuwonm
  • 1,315
  • 11
  • 17
0

To obtain an array of strings that contains all rooms in v4 you can use:

// if you are not using namespaces
Array.from(io.of("/").adapter.rooms.keys());
// if you are using namespaces
Array.from(io.of("/your-namespace").adapter.rooms.keys());
// output: ["room1", "room2", ...]
phoenixstudio
  • 1,776
  • 1
  • 14
  • 19
0

You do it like this:

await io.in(roomID).fetchSockets()
ino
  • 1,002
  • 1
  • 8
  • 25