getting how many people are in a chat room in socket.io [duplicate]
Asked Answered
A

8

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;
Amii answered 19/2, 2012 at 19:40 Comment(2)
Some more info would be nice, is the connection made to a regular IRC server or to a custom chat server program?Baler
+1. This seems like it should be easier than it is.Peterus
E
27

If you're using version < 1,

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

Eupheemia answered 19/2, 2012 at 20:47 Comment(4)
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 codePeppermint
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.Peterus
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? :)Storfer
@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.Factorize
P
135

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
    
Peterus answered 26/6, 2014 at 7:54 Comment(4)
this should be the approved answer... the real answerErme
To get ids of all connected clients I used Array.from(io.sockets.sockets.keys(), to get the clients themselves use Array.from(io.sockets.sockets.values()Although
@Although your code should be Array.from(io.sockets.sockets.keys()). You missed a ) :)Dottie
Note that it's a Map now instead of an array: io.sockets.adapter.rooms.get('my_room')Confidential
E
27

If you're using version < 1,

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

Eupheemia answered 19/2, 2012 at 20:47 Comment(4)
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 codePeppermint
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.Peterus
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? :)Storfer
@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.Factorize
L
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.

Leis answered 4/6, 2016 at 4:39 Comment(0)
S
6

In version 1.4.5

var clientNumber = io.sockets.adapter.rooms[room].length;
Scandalmonger answered 20/2, 2016 at 19:9 Comment(0)
K
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

Krilov answered 18/7, 2017 at 7:45 Comment(1)
I am getting all the connected sockets here, regardless of the room.Alliaceous
B
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.

Bribery answered 3/8, 2017 at 6:48 Comment(0)
T
3

I'm using 1.4.6 and this did the trick:

Object.keys(io.sockets.connected).length
Tenpin answered 27/5, 2016 at 22:0 Comment(3)
This method just count in single nodejs.Thriftless
This will count all connected clients in all rooms.Melton
Agreed - it should be Object.keys(io.sockets.in(room).connected).length to get a specific room.Ilmenite
A
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;
Archival answered 26/10, 2017 at 16:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.