Tracking Online Users

Tracking online users in a web application is a common feature for platforms such as forums, chat applications, and multiplayer games. Here's how you can achieve this:

1. Backend Setup:

a. Use WebSockets:

WebSockets offer a full-duplex communication channel over a single, long-lived connection. When a user connects to your site:

  1. Open a WebSocket connection from the client to the server.
  2. The server can keep track of all active connections.
  3. When the connection is closed (e.g., the user navigates away or loses internet connection), remove that user from the active connections list.

Libraries like socket.io make this process easier.

b. Database:

  1. Add an isOnline boolean field and a lastActive timestamp field to the user's model in your database.
  2. When a user logs in, set isOnline to true and update lastActive with the current timestamp.
  3. When a user logs out or the WebSocket connection is lost, set isOnline to false.

2. Handle Idle Users:

a. Use a Heartbeat:

  1. Periodically (e.g., every minute), send a "heartbeat" message from the client to the server using WebSockets.
  2. Update the lastActive timestamp in the database for that user.

b. Automatic Timeout:

  1. On the server, run a periodic task (e.g., every 5 minutes) to check the lastActive timestamp of all users marked as online.
  2. If a user hasn't been active for a certain duration (e.g., 30 minutes), consider them offline and update isOnline to false.

3. Display Online Users:

a. Real-time Updates:

  1. Whenever the online status of a user changes (either becoming online or going offline), broadcast a message to all connected clients with the updated list of online users or just the change.
  2. On the client side, listen for this message and update the UI accordingly.

b. On Page Load:

  1. When a page is loaded, make an API request to fetch a list of online users and display them.

4. Scalability:

If you expect a large number of users, consider:

  1. Using a dedicated in-memory data store like Redis to maintain a list of online users. This avoids frequent DB reads/writes.
  2. Sharding or partitioning your WebSocket servers and using a load balancer.

5. Privacy Considerations:

Always consider user privacy. Allow users to opt-out of displaying their online status if they wish.

Example Implementation:

Here's a basic outline using socket.io:

// Server
const io = require('socket.io')(server);
let onlineUsers = {};

io.on('connection', (socket) => {
    const userId = socket.handshake.query.userId;

    onlineUsers[userId] = true;

    // Broadcast to all clients the updated onlineUsers list
    io.emit('updateOnlineUsers', onlineUsers);

    socket.on('disconnect', () => {
        delete onlineUsers[userId];
        io.emit('updateOnlineUsers', onlineUsers);
    });
});

// Client
const socket = io.connect('server_url', {
    query: {
        userId: 'your_user_id',
    },
});

socket.on('updateOnlineUsers', (usersList) => {
    // Update the UI with the received usersList
});

Remember, this is a simplified overview. Depending on your app's complexity and requirements, you might need additional logic or optimizations.