views:

38

answers:

2

Hello, I'm having trouble figuring out how I can count the number of logged-in users in my application.

What I have: When a user logs in, they get a session (which is used when the user wants to visit a protected page) and the IsLoggedIn column for the user in the users table is set to 1 to indicate that the user is logged in. When the user logs out, the value is set back to 0. Counting the number of 1s in the users table makes it easy to return the number of users logged-in. But...

The Problem: If the user closes the browser without logging out, the value in the database stays 1, indicating that the user is still logged in even though their session has ended when they closed the browser.

Question: Do you haz teh codez? Just kidding. Could some one suggest a proper way of doing this?

Thank you!

+1  A: 

Rather than a IsLoggedIn column, you should add a LastTimeSeen column. Any time a person visits a page you update the column:

UPDATE members SET LastTimeSeen = NOW() WHERE id = $the_user_id

Then to get how many people are on the site at any given moment you use the query:

SELECT COUNT(*) FROM members WHERE LastTimeSeen > DATE_SUB(NOW(), INTERVAL 5 MINUTE)

That shows how many people have viewed a page in the past 5 minutes, which is the best you're gonna get without a much more complicated solution.

mellowsoon
With a some where clauses of course (`WHERE user=ID` ...)
Rudu
Why would you use a where clause like that? He wants to know how many users are logged in. Not if a specific user is logged in.
mellowsoon
@mellowsoon, Is the update statement per user or the last time a page was accessed?
Scott W.
*smacks head* Now I see why Rudu said use a where statement. I thought he was talking about the second query. Yes, I
mellowsoon
Updating my answer to fix my stupidity. :)
mellowsoon
+1  A: 

Just to offer another solution:

if ($user->isLoggedIn()) {
  touch("/writable/path/loggedInUsers/" . $user->id);
}

If you don't need to query this data, a local file touch is far faster than a DB write. To get logged in users, scan the directory for filemtimes under N seconds old.

mrclay
I'd be interested in seeing some tests on that. I suspect updating the db could be faster in many circumstances.
mellowsoon
A 0 byte file touch should take almost no time, even worst case on NFS. Again, this solution trades easy query-ability for speed.
mrclay