Shahid Karimi
Shahid Karimi

Reputation: 4357

socket.io determine if a user is online or offline

We can trace if a connection is established or disconnected by this code

console.log('a user connected');
    socket.on('disconnect', function () {
        console.log('user disconnected');
    });

Well, its fine. But how can we determine what user connected or gone offline. My client is written in PHP/HTML so they have a user ID.

Upvotes: 39

Views: 63443

Answers (3)

turivishal
turivishal

Reputation: 36114

In addition of @galethil's answer, What if user opens more than one tab (socket connection), each tab (socket connection) has unique socket id for single user, so we need to manage array of socket ids for particular user,

Client Side Connection: Support Socket IO Client v3.x,

<!-- SOCKET LIBRARY IN HTML -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.5/socket.io.js"></script>
const host = "http://yourdomain.com";
// PASS your query parameters
const queryParams = { userId: 123 };
const socket = io(host, {
    path: "/pathToConnection",
    transports: ['websocket'],  // https://stackoverflow.com/a/52180905/8987128
    upgrade: false,
    query: queryParams,
    reconnection: false,
    rejectUnauthorized: false
});

socket.once("connect", () => {
    
    // USER IS ONLINE
    socket.on("online", (userId) => {
        console.log(userId, "Is Online!"); // update online status
    });

    // USER IS OFFLINE
    socket.on("offline", (userId) => {
        console.log(userId, "Is Offline!"); // update offline status
    });

});

Server Side Connection: Support Socket IO Server v3.x,

  • Dependencies:
const _ = require("lodash");
const express = require('express');
const app = express();
const port = 3000; // define your port
const server = app.listen(port, () => {
  console.log(`We are Listening on port ${port}...`);
});
  • Connection:
const io = require('socket.io')(server, {
    path: "/pathToConnection"
});

let users = {};

io.on('connection', (socket) => {
  let userId = socket.handshake.query.userId; // GET USER ID
  
  // CHECK IF USER EXISTS
  if (!users[userId]) users[userId] = [];
  
  // PUSH SOCKET ID FOR PARTICULAR USER ID
  users[userId].push(socket.id);
   
  // USER IS ONLINE BROAD CAST TO ALL CONNECTED USERS
  io.sockets.emit("online", userId);

  // DISCONNECT EVENT
  socket.on('disconnect', (reason) => {

    // REMOVE FROM SOCKET USERS
    _.remove(users[userId], (u) => u === socket.id);
    if (users[userId].length === 0) {
      // USER IS OFFLINE, BROAD CAST TO ALL CONNECTED USERS
      io.sockets.emit("offline", userId);

      // REMOVE OBJECT
      delete users[userId];
    }
   
    socket.disconnect(); // DISCONNECT SOCKET
  });

});

GitHub Demo

Upvotes: 15

galethil
galethil

Reputation: 1016

If your clients have specific user IDs they need to send them to socket.io server. E.g. on client side you can do

// Browser (front-end)
<script>
 const socket = io();
 socket.emit('login',{userId:'YourUserID'});
</script>

And on server you will put something like

// server (back-end)
const users = {};
io.on('connection', function(socket){
  console.log('a user connected');

  socket.on('login', function(data){
    console.log('a user ' + data.userId + ' connected');
    // saving userId to object with socket ID
    users[socket.id] = data.userId;
  });

  socket.on('disconnect', function(){
    console.log('user ' + users[socket.id] + ' disconnected');
    // remove saved socket from users object
    delete users[socket.id];
  });
});

Now you can pair socket ID to your user ID and work with it.

Upvotes: 66

MBK
MBK

Reputation: 3354

We can identify the socket id in server who is connected and who is disconnected. So you can do something like this. You can use this setup if you have an identifier in client side

CLIENT

socket.emit('login', userId);

SERVER SIDE

const users = {};
io.on("connection", (socket) => {

   socket.on("login", (data) => {
      users[socket.id] = data;
    });

  socket.on("disconnecting", (reason) => {
    
    delete users[socket.id]; // remove the user. -- maybe not the exact code
  });
});

Hope you get the idea.

Upvotes: 3

Related Questions