views:

508

answers:

8

Is there a way I can piggy back sessions to know is the user is online?

I.e: use logs on, I set a $_SESSION variable, user times out- cookie Garbage collector updates the database to update their status as offline.

EDIT: I want a solution that does not involve times or dates. I want something to ride on sessions or something similar. Guessing if someone is online is not good enough for what I need.

+1  A: 

Store the time-zone in the table, and use it in a calculation to find that users local time in comparison to the local time of the user viewing the page.

Edit:

Better yet, store all times as the server time, and base all calculations relative only to the server time.

Ian Elliott
+2  A: 

It sounds like your "is the person online" comparison logic isn't taking into account the timezones. If you are dealing with timezones in this manner, I strongly recommend that you store all your times in GMT, and convert them to local time for your users right before you display them. This will make any comparison operations very simple.

There's a nice SO thread about timezones here.

zombat
+1 for GMT. Second best is using Server Time. But if you ever need to move the server across timezones, that screws up all your historical data. Far better to store datetimes in GMT. Server Time also works on an internal database only accessed from a single location (like an office). But even offices can move.
jmucchiello
+21  A: 

Don't bother with figuring out the differences between timezones. That's not necessary.

Whenever the user accesses a page, update a field in their record of the Users table last-updated-time. Then do a query for all users having a last-updated-time within the last 5 minutes. Anything more than this, and they are considered "offline."

If you use your server-time, via the NOW() function in MySQL, you'll side-step calculating differences between timezones.

This is the standard way of tracking how many users are presently online (Meaning, active within the last couple of minutes).

Constantly Updated

If you would like to know they are still active even when they're not jumping from page to page, include a bit of javascript to ping your server every 60 seconds or so to let you know they are still alive. It'll work the same way as my original suggestion, but it will update your records without requiring them to be frantically browsing your site at least once every five minutes.

setInterval("imStillAlive()", 60000);

function imStillAlive() {
  /* Posts to updatestatus.php which updates
     their last_activity_time field within the
     user table on their record */
  $.post("/updatestatus.php"); #jQuery's $.post method
}
Jonathan Sampson
A: 

Depends on your situation, it may be better for you to create a separate table "whose-online" with the columns: "ip" and "last-updated-time" and query/update this table every time a user loads a page.

On page load queries may include:

  1. Update/insert "whose-online" table for current user based on ip.
  2. Delete "expired" rows (can also be done periodically using cronjob).
  3. Count "active" users.

Benefits of using this technique:

  1. If a user is not logged in, he/she is still being counted/tracked.
  2. Depends on the amount of users you have, querying this table may be quicker.

Note: If you use this you should want to take into consideration that any pageview will create a row in your table so based on useragent you can disregard bots or only count the popular ones (Firefox, IE, Safari, Opera, etc).

GiladG
+3  A: 

What you are asking for (after the clarification) is, by definition, impossible. HTTP is a connectionless protocol, so as soon as a user has hit a page and all the content comes back from the server to the user's browser, there is no connection between the two. Someone is "online" with your website for less than a second.

One thing you could do is to have JavaScript on your web page make AJAX requests back to your server on a regular basis which includes identifying information, and a different AJAX request when the user leaves the page, using window.onbeforeunload.

dj_segfault
A: 

One thing I would advise is to store this kind of information in memory with for example memcached or mysql heap or redis. Because otherwise the database will be hit a lot.

Alfred
A: 

The solution that I have implemented for this is to, on every page load by an authenticated user, set/reset a memcache var such as "user_{userid}isonline" => true and expire it in 5 minutes. Then check if the var is in the cache when I access the user's info. Depending on the size of your user base, if you want to get a list of everyone online, you could use a memcache getmulti call with an array of "user{userid}_isonline" keys for all of your users.

of course, this really depends on how often a user will change pages on your site... to get a more accurate representation of the users online, you could implement an ajax xmlhttprequest call on your page running at a small interval (30 seconds or so) that resets the memcache var, and have the memcache var expire in less time (1 minute to account for possible browser issues). This is not COMPLETELY accurate, but as http does not have a persistent connection to the server, you are pretty limited on what you can do.

IF you require an up to the second representation of who is online, you could maybe have a flash app loaded in your page that connects to a jabber server, then just check if that particular user is logged in on the server.

Jason
+2  A: 

My way may not be the best way but since my site and userbase is all in mysql DB, when a user logins into my site,

  1. I update the user table to say they are online
  2. Insert them into an Online table
  3. Then I set a session with the current time

Then on every page load I check for the online time session, if it exist, I check to see how old it is, if it is less then 5 minutes old, I do nothing, if it is older then 5 minutes, then I update the session time again with current time and also update the online users table with the time

Then I have a cron job that runs every 10 - 15 minutes that deletes any uses from online table and marks there user table as offline if there online time has updated within X amount of minutes

jasondavis