Is there a way I can piggy back sessions to know if the user is online?
I.e: use logs on, I set a $_SESSION variable, user times out- cookie Garbage collector update
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.
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:
Benefits of using this technique:
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).
Here's a way on how to get the difference between two dates from a database in minutes, then check for the difference and set the online/offline status.
$query = 'SELECT * FROM Users';
$result = mysqli_query($mysqli, $query);
foreach($result as $user){
// date from the database
$dbLastActivity = date("d-m-Y h:i:s a", strtotime($user['lastOnline']));
// date now
$now = date("d-m-Y h:i:s a", $date);
// calculate the difference
$difference = strtotime($now) - strtotime($dbLastActivity);
$difference_in_minutes = $difference / 60;
// check if difference is greater than five minutes
if($difference_in_minutes < 5){
// set online status
$updateStatus = 'UPDATE Users SET Status="online" WHERE lastOnline="'.$user['lastOnline'].'"';
} else {
// set offline status
$updateStatus = 'UPDATE Users SET Status="offline" WHERE lastOnline="'.$user['lastOnline'].'"';
}
// check if mysqli query was successful
if (!$mysqli->query($updateStatus)){
printf("Error Message %s\n", $mysqli->error);
}
}
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.
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).
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.
var stillAlive = setInterval(function () {
/* XHR back to server
Example uses jQuery */
$.get("stillAlive.php");
}, 60000);
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,
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