42

I have this code right now that sets the nick and room:

io.sockets.on('connection', function(client){
    var Room = "";
    client.on("setNickAndRoom", function(nick, fn){
        client.join(nick.room);
        Room = nick.room;
        client.broadcast.to(Room).emit('count', "Connected:" + " " + count);
        fn({msg :"Connected:" + " " + count});
    });

I wanted to know how I could get how many people are connected to a specific chatroom...like Room.length

client side :

function Chat(){
    this.socket = null;
    this.Nickname = "";
    this.Room = "";
    var synched = $('#syncUp');
    this.Connect = function(nick, room){ 
        socket =  io.connect('http://vybeing.com:8080');    
        Nickname = nick;
        Room = room;
        //conectarse
        socket.on('connect',function (data) {
            socket.emit('setNickAndRoom', {nick: nick, room: room}, function(response){
                $("#connection").html("<p>" + response.msg + "</p>");
            });
        });
}

I found this, but it gives undefined:

count = io.rooms[Room].length;
re1man
  • 2,337
  • 11
  • 38
  • 54

8 Answers8

131

For socket.io versions >= 1.0:

Note that rooms became actual types with a .length property in 1.4, so the 1.4.x method should be stable from now on. Barring breaking changes to that type's API, of course.

To count all clients connected to 'my_room':

1.4+:

var room = io.sockets.adapter.rooms['my_room'];
room.length;

1.3.x:

var room = io.sockets.adapter.rooms['my_room'];
Object.keys(room).length;

1.0.x to 1.2.x:

var room = io.adapter.rooms['my_room'];
Object.keys(room).length;

This is assuming you're running with the default room adapter on a single node (as opposed to a cluster). Things are more complicated if you're in a cluster.


Other related examples:

  • Count all clients connected to server:

    var srvSockets = io.sockets.sockets;
    Object.keys(srvSockets).length;
    
  • Count all clients connected to namespace '/chat':

    var nspSockets = io.of('/chat').sockets;
    Object.keys(nspSockets).length
    
kdbanman
  • 10,161
  • 10
  • 46
  • 78
27

If you're using version < 1,

var clients = io.sockets.clients(nick.room); // all users from room

Sơn Trần-Nguyễn
  • 2,188
  • 1
  • 26
  • 30
  • 8
    just a reminder, this will return an array of the sockets in the room. So to get the amount of people in the room, be sure to append .length to the above code – levi Jun 18 '12 at 21:21
  • 12
    `io.sockets` returns the default `Namespace` (`'/'`). As of socket.io 1.0.x, `Namespaces` do not have a `.clients()` method. I just tested it, `io.sockets.clients === undefined`. This answer will not work anymore. – kdbanman Jun 26 '14 at 08:05
  • this is not true. Is the number of sessions, not users... If the same user have 3 browser tabs, the number of clients in your case increase in 3 users more. How to get the real number of connected users in a room? :) – Aral Roca Oct 12 '15 at 09:22
  • 1
    @AralRoca for all intents and purposes, a count of sessions IS the real number of users in a room. you can't tell the difference between multiple sessions on the same IP, for all you know that could either be 3 tabs, or three different computers on a work network. – Kevin B May 02 '18 at 21:49
7

For socket.io 1.4.6, what worked for me is specifying the namespace in addition to the room. When using the default namespace, you can just specify it as ['/']. For example, to get the number of clients connected to the room 'kitchen' in the default namespace (nsps), you would write:

var io = require('socket.io')();
io.nsps['/'].adapter.rooms['kitchen'].length

Heads up: If no one has joined a room, it hasn't been created yet, therefore io.nsps['/'].adapter.rooms['kitchen'] will return undefined. If you try to call .length on the undefined kitchen your app will crash.

Iron John Bonney
  • 2,451
  • 1
  • 17
  • 14
6

In version 1.4.5

var clientNumber = io.sockets.adapter.rooms[room].length;
Márton Vető
  • 95
  • 2
  • 6
5

I wanted to get a list of users in a room. This ended up being my solution.

I added a username property to my socket, but for completeness I changed that to "id" which is the id of the socket.

var sockets = io.in("room_name")
Object.keys(sockets.sockets).forEach((item) => {
  console.log("TODO: Item:", sockets.sockets[item].id)            
})

Socket.io v2.0.3

The Lazy Coder
  • 11,560
  • 4
  • 51
  • 69
4

For socket.io v2.0.3, I ended up running a redis server and use socket.io-redis plugin. Then you can do:

io.of('/').adapter.clients(['room1', 'room2'], (err, clients) => {
  console.log(clients); // an array containing socket ids in 'room1' and/or 'room2'
});

code is from https://github.com/socketio/socket.io-redis#redisadapterclientsroomsarray-fnfunction

kevzettler pointed me to socket.io-redis


The other answer for socket.io v2.0.3 from The Lazy Coder didn't work for me, it gave me a list of all connected clients, regardless of the room.

Dries Cleymans
  • 770
  • 8
  • 20
3

I'm using 1.4.6 and this did the trick:

Object.keys(io.sockets.connected).length
Alex Klibisz
  • 1,313
  • 1
  • 14
  • 21
0

put this in a function and it will give you failsafe to prevent crashing:

var roomCount = io.nsps['/'].adapter.rooms[roomName];
if (!roomCount) return null;
return roomCount.length;