javascriptnode.jswebsocketsocket.iosocket.io-redis

socket.io with socket.io-redis: get all socket object in a room


I want to retrieve server side all socket connected in a room.

I have found the method clients that if chained after the method in return all the sockets connected in a room:

import * as express from 'express';
import * as SocketIO from 'socket.io';
import * as redisSocket from 'socket.io-redis';
import * as sharedsession from 'express-socket.io-session';

const app = express();

const redisOption = {port: 6379, host: 'XXX'};

// use the RedisStore as express session
const session = session({
  name: 'SESSIONID',
  store: new RedisStore(redisOption),
  secret: 'Ashg8hV77bxFeyLVec',
  resave: false,
  saveUninitialized: false
});
app.use(session);

// start express server
const httpServer = app.listen(80);

// attach the express app to socket.io server
const socketServer = SocketIO(httpServer, { path: '/api/socket.io', origins: '*:*' });

// set redis as socket adpter for multi instance/nodes
socketServer.adapter(redisSocket(redisOption));

// share the express session with socket.io
socketServer.use(sharedsession(session, {autoSave: true}));

// get all client in a room
socketServer.in(room_id).clients((err, clients) => {
    for (let i = 0, e = clients.length; i < e; i++) {
        const client = clients[i];
        console.log(client); // print the socket id

        // HOW RETRIVE THE SOCKET OBJECT???
    }
});

But i need to retrive all sockets session/handshake.

There is a way for retrive all sockets session/handshake?

SIDE NOTE: the socket server is multi instance/nodes with socket.io-redis


Solution

  • I am not sure below code will work, but I think by using customHook provided by socket.io-redis, We can get redis based multi-node's socket.handshake.session.

    I hope the code below helps.

    // get all client in a room
    socketServer.in(room_id).clients((err, clients) => {
        for (let i = 0, e = clients.length; i < e; i++) {
            const client = clients[i];
            console.log(client); // print the socket id
    
            // HOW RETRIVE THE SOCKET OBJECT???
        }
    });
    
    // set root namespace
    const rootNamespace = socketServer.of('/');
    
    // define customHook
    rootNamespace.adapter.customHook = (request, cb) => {
        // every socket.io server execute below, when customRequest requested
        const type = request.type;
        if(type === 'getHandShakeSession'){
            // get all socket objects on local socket.io server
            const sockets = rootNamespace.connected;
            const socketIDs = Object.keys(sockets);
            // get all socket.handshak.session array on local socket.io server
            const sessions = socketIDs.map(socketID => sockets[socketID].handshake.session);
            cb(sessions)
        }
        cb()
    }
    
    // request customRequest
    rootNamespace.adapter.customRequest({type:'getHandShakeSession'},(err,replies) => {
        //replies are array which element was pushed by cb(element) on individual socket.io server
        //remove empty reply 
        const filtered = replies.filter(reply => reply !== undefined)
        // filtered seems like [[session1,session2,...],[sesssion3,session4,...],..]
        console.log(filtered)
    } )