With the evolution of today's technologies, efficiently tracking online users has become imperative. Depending on the online or offline status of users, certain application features may be activated or deactivated.
Traditional Method
Historically, the solution for monitoring user status was to employ a client-side pinging mechanism. Here, the browser communicates with the server when a user logs in, sending periodic pings to indicate that the user remains active. The server is then informed once the user logs off. However, this strategy has shortcomings, failing to account for scenarios like:
- The abrupt closure of a browser tab by the user.
- Loss of internet connectivity for the user.
To rectify this, a server-side purging method was introduced. This mechanism checks at set intervals if a user's last timestamp surpasses a specified duration (e.g., a minute). If it does, the user is deemed offline, removed from the online_users list, and the updated list is broadcasted. While effective in theory, in practice, this method could result in gaps. A user might already be offline, but the system, due to the delay in purging, might still consider them online.
Cogency's Solution
At Cogency, we're convinced there's a more refined solution using WebSockets. Our methodology, inspired by this StackOverflow post link, that leverages the capabilities of WebSockets.
Understanding WebSockets
WebSockets shine in real-time web applications. Imagine an interview scheduling app: every time an interview is set or cancelled, the calendar must reflect these changes instantly. WebSockets present the perfect remedy, ensuring users always see the most updated calendar. Furthermore, for platforms like chat applications where users constantly exchange messages, WebSockets facilitate the server in accurately routing these messages amidst concurrent conversations. For a comprehensive grasp of WebSockets and their applications, delve into this insightful article here.
Step 1: Setting up the WebSockets server
let onlineUsers = [];function addOnlineUser(ws){if (!onlineUsers.includes(ws.user_id)){onlineUsers.push(ws.user_id);app.publish(ws.channel, JSON.stringify({type: 'onlineUsers',body: {onlineUsers}}));}}function removeOnlineUser(ws){onlineUsers.find((user_id, index) => {if (user_id === ws.user_id){onlineUsers.splice(index, 1);app.publish(ws.channel, JSON.stringify({type: 'onlineUsers',body: {onlineUsers}}));}});}
Step 2: Setting up the client-side
let onlineUsers = [];function getOnlineUsers(){return onlineUsers;}function isUserOnline(user_id){return _.includes(getOnlineUsers(), parseInt(user_id));}function setOnlineUsers(onlineUsers=[]){onlineUsers = onlineUsers;}function onWebsocketsMessage(message){if (message.type==='onlineUsers')setOnlineUsers(message.body.onlineUsers);}
The magic stems from the innate characteristics of WebSockets. Periodically, the client-side sends pings to the server, which in turn responds with pongs. This exchange allows us to pinpoint who is currently online with precision.
In our Cogency project, we've integrated this solution in a number of places:
- Collaborative meeting notes ( video )
- Collaborative whiteboards ( video )
- Online user status
- Direct one-on-one video calls
- Meeting chat across modules ( video )
- Kanban boards ( video )
The results have been impressively amazing so far! :)