How to store online status

online-identityrediswebsockets

I'm developing realtime web chat using pubsub pattern. To be concrete I'm using python and tornado-redis on back end and websockets (WS) (tornado) on front end. I have WS connection open and close events. So I stuck with the problem what is the best solution to store current online user list.

Here are some theses:

  • I would like to run multiple threads so data about online users should
    persists in accessible for all place. Horizontal scaling requires the same.
  • One user can open multiple connections. Meaning same username can be present in multiple connection instances.

Solutions:

  • Store in nowhere! Meaning when I need current online just broadcast message to all and determine who's online from responses. (+) I know real userlist everytime, (-) this is increasing processing time and complicating implementation).
  • Store current online in database in a separate table. Every table row matches a single connection. (In current realization it's redis hmap. {"hash of current connection" : "username"}. hset on WS opening (a user connects), hdel on WS closing (user disconnects). (+) Fast if I just need to get current online, (-) If a user disconnects and database connection is lost the same time the DB info would be wrong.
  • Specific to redis and my current realization. Since I have a single redis connection per WS connection I can store user info in tornado clientname. Since redis already has info about connected users. I can get client-list, filter it by some criteria (clientname) and get online. (+) I delegate online to redis . (-) Storing multiple online lists becomes complicated. For example if webchat has multiple rooms (lets assume 100) storing online for a every room in a single place looks a bit messy.

Which solution best meets my requirements, or do you have a better solution?

Best Answer

I came across this question on random, but here's how I would do it:

On your users table, create a column called lastActivity and make it a DateTime type.

When connecting via the websocket, have the client authenticate the socket connection, (like sending an authToken or however you like). When authenticating, you set the id of the user as a property on the connection.

After authenticating, have the client send periodic messages to the server.

When the server receives the message, update the lastActivity on the user, use the id you set on the connection to find the user that is sending the message.

Now in your application you can simply compare the lastActivity field, for example if it is older than 10 seconds and you have it set to send a message every 10 seconds, the user could be considered offline.

Related Topic