socket.io determine if a user is online or offline
If your clients have specific user IDs they need to send them to socket.io server. E.g. on client side you can do
<script> const socket = io(); socket.emit('login',{userId:'YourUserID'});</script>
And on server you will put something like
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.
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 parametersconst 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 portconst 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 IS USER EXHIST 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) { // ISER IS OFFLINE BROAD CAST TO ALL CONNECTED USERS io.sockets.emit("offline", userId); // REMOVE OBJECT delete users[userId]; } socket.disconnect(); // DISCONNECT SOCKET });});
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.