1

This turned out to be a rather interesting problem contrary to my expectations.

Imagine a simple chat app, a user registers then can add other users to their contacts list and start conversations.

I want to be able to show in real time each user's online status (for simplicity just online/offline). The problem is how to do that efficiently.

The app utilizes WebSockets so there is a list of connections on the server which eases the task and the most obvious solution is whenever a user connects or disconnects simply broadcast that to all other users. This will obviously not be very efficient because every user that does not have the triggering one in their contact list simply won't care and if the number of users is great so will the wasted bandwidth be.

A more optimized solution would be to have a connecting user ask for the statuses of everyone in their contact list. Then create a list for each user on the server and store the ids of everyone who asked for their status. This way whenever a user connects/disconnects I will have a list of users who care about this and I can broadcast the event knowing that nothing goes to waste. However what I don't like about this is that as you can see there is quite some complexity being added to the scheme as well as keeping such lists on the server will increase the amount of memory used proportionally to the amount of users (which is always the case but it seems too much for such a task).

Since chat apps are not something new I'd like to ask what are the methods used for such functionality in existing apps or if there is a silver bullet solution that is well known.

1

Connection/disconnection events are likely to be very rare, so it doesn't make much sense to optimize this excessively. In particular, disconnects will often happen through a timeout. If that status change is broadcast a few seconds later, this won't matter.

What does matter is privacy implications. Don't broadcast the status to every user, but think about

  • who should be allowed to see the status, and
  • who is interested in that status.

You should only send the notification to the intersection of these groups. For example, all people in my contact list are allowed to see my status change. People are only interested in my status if I am also in their contact list and they are online. If you store the current status and contact list in a database that can be checked with a moderately complex SQL query (two joins). But given appropriate indices, this query will still be quite fast even for a large-ish user base.

Some chat applications don't display the status of all contacts. E.g. the WhatsApp user interface only shows this status in a 1:1 chat with that person. That means status changes only trigger very few notifications, possibly none. But it is then easier to think about this in terms of explicit subscriptions of one user to the status of another user. Maintaining these subscriptions requires very little memory compared with the cost of an open socket.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.