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.