15

I'm not sure what would be the easiest way to do this. I need to be able to detect what users are online on my website. So when people are viewing a thread or something it will say next to the users name if they are ONLINE or OFFLINE. And at bottom of forum index it will say all the users who are online.

What would be the easiest approach to do something like this? I'm not sure if I will need a Javascript which would run every time a page loads or what.

Thanks :)

Cory
  • 732
  • 3
  • 7
  • 22

4 Answers4

25
  • have a MySQL database with a user table
  • have a column in that user table which saves the "last seen"-time
  • update that column on every page request
  • when checking for online or offline, check if current time minus "last seen"-time is greater than some treshold you like

Edit: You could optionally make a javascript "ping" the server (request an empty page) every two minutes or so if you want people idling with your Website open to be displayed as online, too.

thejh
  • 44,854
  • 16
  • 96
  • 107
  • 1
    yeah this is probably the best approach – Breezer Nov 01 '10 at 21:49
  • Exactly what I was thinking. As I was going to have a last seen time. And set online to last seen within 5 minutes or so. Didn't know if that was the best approach though. – Cory Nov 01 '10 at 21:49
  • When do you think the last seen column should update? Every page load? – Cory Nov 01 '10 at 21:50
  • @Cory: That's what I would do. – thejh Nov 01 '10 at 21:52
  • 2
    Regarding this solution's edit: If you decide to ping the server to keep track of "who's online," you may wish to consider update the pinger's "last-seen" entry to reflect this. There are pros and cons to this: It will prevent people who are idling from also timing out their "last-seen", but it will also allow people to walk away from an open browser and continue to appear online when they are not. Your choice. – Brian Bauman Nov 01 '10 at 21:58
  • If you have shell admin access you can run a cron script every - say 5 minutes - to compose an array of users who have been active since the last cron ran, then write that to a flat text file and include it in your header as a variable so you're not constantly pinging the server with this expensive query. – Kai Qing Nov 01 '10 at 23:39
  • Additionally, you could run an ajax script every 2 minutes for the user to cross reference the id's of the users in the html vs the flat text array and update accordingly. At least this way the SQL is handled via cron and is only run once per 5 minutes for all users instead of each user running it individually. – Kai Qing Nov 01 '10 at 23:41
  • One thing I'd like to add to this is being able to detect the number of guests. This is the only thing that's giving me trouble at the moment. – Cory Nov 02 '10 at 00:14
  • @Cory: Give every guest a cookie with a random, long string and create a new table for the guests which contains this string as ID and a timestamp (which is updated every time the guest requests a page). To avoid wasting disk space, you should delete old database entries regularily. – thejh Nov 02 '10 at 23:04
  • I would do javascript ping exemple using cURL, no one would notice it and should work like a bot. – Pedro Gabriel Apr 16 '13 at 19:03
  • I would use in-memory cache rather than DB for "caching" user last access time data. DB calls/connections are usually costly. Using cache, you can even add ttl to automatically evict old data. – Q i Jan 16 '18 at 18:06
3

One approach is to store your users sessions in a database or another store like memchached (or ideally both What is the best way to handle sessions for a PHP site on multiple hosts?). Then you just look up the user in your store and see if their session is still active.

A solution like this: http://pureform.wordpress.com/2009/04/08/memcache-mysql-php-session-handler/

Community
  • 1
  • 1
brendan
  • 29,308
  • 20
  • 68
  • 109
2

You need to hold some kind of a "session" table, where you hold the user and the time of when they visited a page.

If the time is older then 5 minutes the user is offline (and the row can be deleted). The other users in the session table are "online".

Tom Vervoort
  • 536
  • 4
  • 11
0

First thing first, there's no way to accurately get the current online users count. The best you can do is get a rough number.

Think about this situation: a user logs in to your website, clicks some links, and just closes the browser tab without logging out. Actually this is quite common. Your server never knows that a user closes the browser, so the session of that user keeps alive for some time (30 minutes maybe) if the session stored on your server.

In some stateless web apps like Ruby on Rails apps, sessions are stored completely on the browser side (in the cookies), and the server totally forgets about the user after each request, and that makes counting online users nearly impossible. This is a tradeoff for simplicity and scalability.

So how can we get such a number? We must make assumption basing on compromise. We make such an assumption that a user is online if his/her last request was made less than 30 minutes ago, then we can get the number of "online" users by tracking the timestamp of the last request each user makes. Or we can assume that a user is online if his/her session on the server is still alive, and count the sessions on the server. Either way, we have to convince ourselves that the number of "dangling sessions" is negligible (I know it's hard).

Aetherus
  • 8,720
  • 1
  • 22
  • 36