How do I get a list of connected sockets/clients with Socket.IO?

Viewed 304326

I'm trying to get a list of all the sockets/clients that are currently connected.

io.sockets does not return an array, unfortunately.

I know I could keep my own list using an array, but I don't think this is an optimal solution for two reasons:

  1. Redundancy. Socket.IO already keeps a copy of this list.

  2. Socket.IO provides method to set arbitrary field values for clients (i.e: socket.set('nickname', 'superman')), so I'd need to keep up with these changes if I were to maintain my own list.

What should I do?

35 Answers

Update Socket.IO v4.0+ (last checked Jul 13 2022)

I've tried all of the other answers... None of them worked, except this:

The easiest way to get all the connected sockets is through:

await io.fetchSockets()

It returns an array of all connected sockets

Documentation

// Return all Socket instances
const sockets = await io.fetchSockets();

// Return all Socket instances in the "room1" room of the main namespace
const sockets = await io.in("room1").fetchSockets();

// Return all Socket instances in the "room1" room of the "admin" namespace
const sockets = await io.of("/admin").in("room1").fetchSockets();

// This also works with a single socket ID
const sockets = await io.in(theSocketId).fetchSockets();

Example usages

// With an async function

 const sockets = await io.fetchSockets()
 sockets.forEach(socket => {
    // Do something
 });
// Without an async function

io.fetchSockets()
.then((sockets) => {
  sockets.forEach((socket) => {
    // Do something
  })
})
.catch(console.log)

Version 4.0 and later (2021)

None of the answers worked for me. I will spare you the pain. Their API and documentation have changed greatly since 1.0 onward.

Server API: all available options

But you need to dig deeper here.

// Return all Socket instances
var clients = io.sockets;

clients.sockets.forEach(function(data, counter) {

    //console.log(data); // Maps

    var socketid = data.id; // Log ids
    var isConnected = data.connected // true, false;

});

Socket.IO 3.0

io.in('room1').sockets.sockets.forEach((socket, key) => {
    console.log(socket);
})

It gets all socket instances in room1.

namespace.allSockets()

It returns a Promise<Set<SocketId>>.

io.allSockets(): All connected socket ids in the main namespace

io.in('room').allSockets(): All connected ids in the 'room'

io.of('/namespace').allSockets(): All connected ids in '/namespace' (you can also combine this with rooms)

io.sockets.sockets.keys()

This helps me.

To get a list of socket id's, you can do:

[...io.sockets.sockets].map(s => s[0]);

To get the socket object, do:

[...io.sockets.sockets].map(s => s[1]);

Socket.IO 4.x

const socketsOnDefaultNamespace = io.of('/').sockets.size;
console.log("Number of clients connected: ", socketsOnDefaultNamespace);

const socketsInARoomInSomeNamespace = io
  .of('/someNamespace')
  .in('/someRoomname')
  .fetchSockets()
  .then((room) => {
      console.log("clients in this room: ", room.length);
    });

You can read more in the documentation.

Socket.IO 1.7.3

I used Object.Keys to get the array of the connected socket. Then in the same array iterate with the map function to build a new array of objects:

var connectedUsers = Object.keys(io.sockets.connected).map(function(socketId) {
    return { socket_id : socketId, socket_username: io.sockets.connected[socketId].username };
});

// Test
console.log(connectedUsers);

This should help to get the socket id/username array.

v.10

var clients = io.nsps['/'].adapter.rooms['vse'];
/* 
'clients' will return something like:
Room {
sockets: { '3kiMNO8xwKMOtj3zAAAC': true, FUgvilj2VoJWB196AAAD: true },
length: 2 }
*/
var count = clients.length;  // 2
var sockets = clients.map((item)=>{  // all sockets room 'vse'
       return io.sockets.sockets[item];
      });
sample >>>
var handshake  = sockets[i].handshake; 
handshake.address  .time .issued ... etc.

For Socket.IO version 4.0.0

On the server side, to list some property of all active sockets, I use this:

function listSocketsProperty(myProperty){
  let sck = io.sockets.sockets
  const mapIter = sck.entries()
  while(1){
    let en = mapIter.next().value?.[0]
    if(en) 
      console.log( sck.get(en)[myProperty] )
    else 
      break
  }
}

Explanation:

sck=io.sockets.sockets is a Map object.

The entries() method returns a new Iterator object that contains the [key, value] pairs for each element in the Map object.

en=mapIter.next().value?.[0] gets the key - the first element of a pair.

If there is no more to iterate, en becomes undefined and this breaks the while loop.

Example:

My sockets have property 'playerName', and I want to list names of all active players in all rooms. To do that, I simply call the function:

listSocketsProperty('playerName')

and get something like this in the console:

John
Peter
Zoran
etc.

Easy reference for Socket.IO v4

socket.server.eio.clients
Related