15

I am using socket.io with multiple nodes, socket.io-redis and nginx. I follow this guide: http://socket.io/docs/using-multiple-nodes/

I am trying to do: At a function (server site), I want to query by socketid that this socket is connected or disconnect

I tried io.of('namespace').connected[socketid], it only work for current process ( it mean that it can check for current process only).

Anyone can help me? Thanks for advance.

John Nguyen
  • 711
  • 6
  • 21

4 Answers4

5

How can I check socket is alive (connected) with socketid I tried namespace.connected[socketid], it only work for current process.

As you said, separate process means that the sockets are only registered on the process that they first connected to. You need to use socket.io-redis to connect all your nodes together, and what you can do is broadcast an event each time a client connects/disconnects, so that each node has an updated real-time list of all the clients.

Tristan Foureur
  • 1,647
  • 10
  • 23
  • Hi, I mean I want to check socket is connected or not with socketid. it not mean check socket is connected or not. your approach can not solve 2 problem: 1. I have socketid, I want to check there are socket is connected or not? 2.The event connect and disconnect will fire asynchronously. maybe actually It connect first and disconnect later, but on server,because of many reasons the disconnect event fire first and connect later. So actually it is disconnect but on server store it connected – John Nguyen Apr 13 '15 at 01:16
  • Please update your comment as I don't really understand what you're trying to do. Each node **should not** have all the socketIds but it's okay if **one node** queries all the nodes with a socketId to see if it's there. Just add a layer of communication between your nodes if you really want to query by socketid. – Tristan Foureur Apr 14 '15 at 21:29
  • I am trying to do: At a function on 1 node, I want to query by socketid that this socket is connected or disconnect. It's not easy to make a layer of communication between nodes by the way sent a message to all of nodes and get return value to check socket is connected or disconnect. you can reference at http://socket.io/docs/rooms-and-namespaces/#sending-messages-from-the-outside-world – John Nguyen Apr 15 '15 at 02:04
  • If posible, you can give me snippet code, on idea, it's easy but actually it's so difficult thanks – John Nguyen Apr 15 '15 at 02:08
2

Check out here

as mentioned above you should use socket.io-redis to get it work on multiple nodes.

var io = require('socket.io')(3000);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
Community
  • 1
  • 1
vromanch
  • 939
  • 10
  • 22
  • I am using it (socket.io-redis), I think you don't understand my question. I am trying to do: At a function on 1 node (server side), I want to query by socketid that this socket is connected or disconnect – John Nguyen Apr 16 '15 at 01:06
  • everything is right. socket.io is using sessions by default which is not shared throw multiple app instances. Shared memory will do the trick ( redis, mongodb, any storage... ). socket.io-redis that's only interface to interact with redis. make sure you configured the same prefix. try out any redis GUI to watch and test it locally ( also you can get any information by socket id directly from redis storage ) – vromanch Apr 16 '15 at 01:38
  • If posible, you can give me snippet code. Tried for long time but not success – John Nguyen Apr 16 '15 at 01:46
2

I had the same problem and no solution at my convenience. So I made a log of the client to see the different methods and variable that I can use. there is the client.conn.readystate property for the state of the connection "open/closed" and the client.onclose() function to capture the closing of the connection.

const server = require('http').createServer(app);
const io = require('socket.io')(server);
let clients = [];
io.on('connection', (client)=>{
    clients.push(client);
    console.log(client.conn.readyState);
    client.onclose = ()=>{
        // do something
        console.log(client.conn.readyState);
        clients.splice(clients.indexOf(client),1);
    }
});
Taur
  • 514
  • 3
  • 8
0

When deploying Socket.IO application on a multi-nodes cluster, that means multiple SocketIO servers, there are two things to take care of:

Using the Redis adapter and Enabling the sticky session feature: when a request comes from a SocketIO client (browser) to your app, it gets associated with a particular session-id, these requests must be kept connecting with the same process (Pod in Kubernetes) that originated their ids.

you can learn more about this from this Medium story (source code available) https://saphidev.medium.com/socketio-redis...