In this blog, I’ll explain how to create a system that monitors users’ online and offline status after they log into an application.
Before we begin, let’s make a list of the steps.
- The user must first log in to the application.
- As soon as the user checks in, a socket is created, and the client alerts the server that the user is online. The user’s state will be changed from offline to online.
- The client will notify the server that the user is offline when user closes the tab. The user will be switched from being online to offline.
These are the three steps we’ll follow. By doing this, we can guarantee that a user is online when using our application and offline when not (in the case of closing the tab or switching to another).
Let’s start by coding the server-side.
Create a node.js project in a folder called "server." To create it, simply execute npm init inside the server folder.
After creating our node.js project, we’ll need to install some packages.
npm install --save socket.io express cors http
Create a file called index.js and write these lines of code.
import express from "express";
import cors from "cors";
const http = require('http');
const app = express(); //calls the function express()
// and puts new Express application inside the app variable
const server = http.createServer(app); // creates a server
const io = require("socket.io")(server, { //init the server
cors: {
origin: "http://localhost:3000", //by writing an origin like this,
// server will only allow requests from localhost:3000
},
});
Now that we have created our io variable, we can use it for socket operations. All our socket operations will be inside the “connection” event. It’s an event that gets triggered on a new socket connection.
let onlineUsers = [];
io.on("connection", (socket) => {
// add new user
socket.on("new-user-add", (newUserId) => {
if (!onlineUsers.some((user) => user.userId === newUserId)) {
// if user is not added before
onlineUsers.push({ userId: newUserId, socketId: socket.id });
console.log("new user is here!", onlineUsers);
}
// send all active users to new user
io.emit("get-users", onlineUsers);
});
socket.on("disconnect", () => {
onlineUsers = onlineUsers.filter((user) => user.socketId !== socket.id)
console.log("user disconnected", onlineUsers);
// send all online users to all users
io.emit("get-users", onlineUsers);
});
socket.on("offline", () => {
// remove user from active users
onlineUsers = onlineUsers.filter((user) => user.socketId !== socket.id)
console.log("user is offline", onlineUsers);
// send all online users to all users
io.emit("get-users", onlineUsers);
});
});
We now have a method for handling user log-ins and log-outs. We can now move on to the client side because the server side is complete.
For this project, we’ll use React. Execute this line in the terminal to create a React application.
npx create-react-app my-app
A login page, chat list page, and chat page are required for our React application. I won’t present every component because the sole purpose of this blog is to demonstrate how to use sockets for user status. Having said that, let’s examine socket usage on the client side.
// Connect to Socket.io
useEffect(() => {
socket.current = io("ws://localhost:5000");
socket.current.emit("new-user-add", user._id);
socket.current.on("get-users", (users) => {
setOnlineUsers(users);
});
}, [user]);
useEffect(() => {
// Tab has focus
const handleFocus = async () => {
socket.current.emit("new-user-add", user._id);
socket.current.on("get-users", (users) => {
setOnlineUsers(users);
});
};
// Tab closed
const handleBlur = () => {
if(user) {
socket.current.emit("offline")
}
};
// Track if the user changes the tab to determine when they are online
window.addEventListener('focus', handleFocus);
window.addEventListener('blur', handleBlur);
return () => {
window.removeEventListener('focus', handleFocus);
window.removeEventListener('blur', handleBlur);
};
}, [user]);
This is how I use Socket.io to monitor user status. Since I’m just learning about Socket.io and am not yet confident in my skills, if I made a mistake, kindly let me know.
You can find the entire project here source code