List of currently logged in users

How to get a list of all users who are currently logged in right in your app?

I’m not sure how to get an exact number.

However, if I just wanted an estimate, I would use the ā€œlast_loginā€ timestamp in the Users table to return those who logged in very recently (like a second ago).

That kind of sounds silly, but I’m not sure how to be more precise (and I may be missing something obvious).

Could you tell us what you would use this information for?

I will use it to show who is online and who is not.

I would use it to do data maintenance. When a user is not logged in, then it is safe to back up their data, upgrade it to current app standards, etc.

In fact, I would really like a way to be notified when a user’s session ends, e.g., a hook, or callback function, to be triggered when that happens.

After all, we can’t count on the user clicking a Logout button. Many will just close their browser (or power-off their computer – or a lightning strike will do that for them).

1 Like

And therein, I think, lies the problem. You don’t necessarily get a signal when the user ends the session (as opposed to the server session timing out).

In the absence of a signal from Anvil when the session is terminated, you could update a time/date field in the user’s table every time a server call is made (or some criteria), possibly make it a decorator around every server function. Then poll (externally using an API for now until scheduled tasks are available) for any time/dates over 30 mins (which I think is the session timeout) and assume they are dead. You can then signal as required.

A bit hacky, I agree. But it could work.

Just an idea.

2 Likes

You could use a Timer to run a server function periodically that updates a ā€˜last seen’ column in the Users table. That way you could get all users who were seen in the last 5 seconds. Something like this:

from datetime import datetime
from datetime import timedelta

@anvil.server.callable
def get_logged_in_users():
  app_tables.users.search(
    last_seen=q.greater_than(datetime.now() - timedelta(seconds=5))
  )

I would only do this if your app really needs a list of all logged-in users: there’s no point in polling the back-end unless you need to, which is why we don’t do it by default.

2 Likes

Depending on how session timeout is processed, server-side, a end-of-session trigger might not need polling. For example, if you’ve stored an object in the session cache, and the object has a __del__ method, does that method get called? (But maybe we can’t store such objects in the cache…)

Even if it does need polling, it only needs it for those Sessions which have specifically asked for such a trigger.