timed auto logout and browser close - php

I've created a very simple multiuser game for learning purposes.
As users log on, each other user gets an update of all currently logged in users.
When a user logs in, it simply sets a value for that user in the SQL database to 1. When they're logged out, the value should be 0.
I'm using $(window).unload(function() {}); to try to catch tab/browser closes, but it only sortof works.
Two questions:
Is there a better way to catch browser or tab close?
In the event that it misses the tab close, or their machine crashes, or internet connection dies, or the user simply walks away from the machine, I want to go ahead and log them out automatically.
I'm using an HTML/Jquery frontend with PHP backend. What can I do to accomplish the second question? I assume I need to do it in PHP.. we're working under the assumption that the browser is likely no longer even around, hence not processing jquery stuff. Can PHP do something on an continuous timer that checks to see if the user is still around... without simply having the users click a button every 10 seconds?
Edit:
There's a potential solution here: How to detect if a user has logged out, in php?
But I'm using ajax to avoid page refreshes. Ideally, the user will never f5 the page, or click any buttons (I'm testing, remember, this is not a for real app). Will PHP see last activity without a full page refresh?
Edit2:
I've added the following code to my PHP, with a corresponding jquery function using setInterval
if (isset ($_POST['keepalive'])) {
if (filter_input(INPUT_POST,'keepalive') == '1') {
$name = $_SESSION['name'];
$time = time();
mysql_query("UPDATE tictac_names SET keep_alive = '$time' WHERE name ='$name'") or die(mysql_error());
}
}
This plugs a unix epoc timestamp into my table, which will be super easy for simple calculations.
My question now is: How do I tell PHP to run a check for each logged in user ever X number of seconds? My PHP backend file is primarily just set to catch post variables and run code, then hand it back to jquery. Since this code is intended to log out inactive browsers/users, I can't rely on jquery sending a request to PHP, and there's no refresh of the PHP. Do I need to do some kind of cron job or some bizarreness to get PHP to check for all users who have not updated in the last X seconds?
Help!

Don't know about the first question, but how about a suggestion on the second:
When the user is 'active', will they be causing page requests fairly regularly? If so, you could have a system whereby a logged-on user is periodically logged in your SQL database, with a timestamp. Then have another script look up all those users whose timestamps are older than a specified period (whatever you like, eg 10 seconds) and have them set to '0'.
I could suggest some code but maybe this isn't what you're looking for - let me know.
EDIT: OK, the link from your edit seems to have been answered with a similar system to what I just suggested. If you use AJAX you can call a php script periodically in the background to set and check timestamps from the SQL table.

You could implement a $_SESSION based solution, like Gumbo answered this question. Then you could adapt it to handle your database requirements.

if you used html5 socket connections as your way of connecting to the server, your socket server script would know when a subscriber disconnects. this would also allow you to push data to all the clients in real time without long polling. the only problem is I don't know what the support of html5 sockets is at the moment. I have done something similar using Flash, which also supports socket connections.

Instead of just setting a flag when a user logs in, log a timestamp you can use to determine the time of log-in. Also, you can have your client, call-home using AJAX some PHP script to save in the database the timestamp of last user-activity.
You can then execute a session cleaner script periodically using a cron job in the server. The script would query the database to detect the stale sessions and do the log-off (set the logged on flag to 0). If the server has PHP CLI (Command Line Interface) installed, you can code the script in PHP.

A possible way to only catch a user who comes back to the site after they closed the window could be using a database for user ID, IP and time like so:
$_SESSION['ip'] = $_SERVER['HTTP_CLIENT_IP'];
if(isset($_SESSION['ip'])){
if(Logedin){ // This login detection can be set by cookies can very depending on situation
mysql_query("INSERT INTO users SET user_login=\"".'1'."\",user_id=\"".$idfromlogin."\",user_ip=\"".$_SESSION['ip']."\",user_time=\"".time();."\"");
}
Then we can check this every time a page loads against the time(); if the user closes window by "X" button the session is over. Now we have to start a new session but that's why we saved the time in the database.
$_SESSION['ip'] = $_SERVER['HTTP_CLIENT_IP'];
if(isset($_SESSION['ip'])){
if (!$sql = mysql_query("SELECT * FROM users WHERE user_ip=".$_SESSION['ip'])){
die('Error: ' . mysql_error());
}
$row = mysql_fetch_array($sql);
if ($row['user_time'] + 10 * 60 < time()){ // this is 10 minutes have passed
// now to find the user database by the session database the logins is your method of loging in a user from logins database with pass and name
if (!$user = mysql_query("UPDATE logins SET user_isloggedin=\"".'0'."\" WHERE user_id=".$row['user_id'])){ //from the users database
die('Error: ' . mysql_error());
}
}
This only shows a way to check IP if they came back and the recorded time has passed previous. This does not show how to catch when some one presses "X" button. IP's can change so I would write a check IP function:
function getRealIpAddr(){
if (!empty($_SERVER['HTTP_CLIENT_IP'])){ //check IP from share internet
$ip=$_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){ //to check IP is pass from proxy
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}

I assume that, users are shown as online and offline on logout. Destroying session or cookie will require client browser in working mode.
Solution
I also assume there is a timestamp column maintained. Set an interval to check time-gap between current TS and Last Timestamp. Also update your own TS against your id to current TS.
setInterval(function(){
$.ajax({
url: "/backend.php?userid=id",
success: function(resoponse){
console.log(response);
}
});
}, 10000);
backend.php
$user_id = $_GET["userid"];
$query = "select * from table name where (GETDATE() - timestamp) > 60";
$resut = mysqli_query($con, $query);
while($row = mysqli_fetch_assoc($result)){
//set there status = 0 as offline
$other_user_id = $row['user_id'];
mysqli_query($con, "update tablename set status = 0 where user_id = '$other_user_id'");
}
//update your own timestamp
mysqli_query($con, "update tablename set timestamp = GETDATE() where user_id='$user_id'");
This would check user activity, or basically check if that js is running or not. If browser was closed then TS for that user won't get updated hence GETDATE() - timestamp will be greater than 60. Now other users who would be running the web app would also run the same script, checking and updating all users status as per condition.
When user closes his tab he would still be online for at least 1 minute.
I had a similar problem and found solution here PHP auto logout on tab close.

Related

how to check user is online or not in real TIME

I'm currently trying to display all online users on my SITE'S userpage using the php session variables. To do this, whenever a user logs in or out, a column in a database gets set to "1" or "0".. However this doesn't entirely work since the database doesn't get updated when the user closes their browser (and therefor destroys the session). So is there another way of checking if a certain sessionid is set??
I also want to know how the twitter and facebook handle this ?
You almost have it. The way that the vast majority of sites deal with the issue is to have a table like you do, but they add a timestamp to it and update the timestamp when a new page is loaded.
When querying the table, you simply look for say the last five minutes of active users and they are the "live" users on the site.
Technically, you don't even need to keep the "logged in/out" value in that table. If they have been logged in within the lat five minutes, they are probably still about.
There is no guaranteed, sure-fire, totally bullet-proof way of checking if a user is there or not. You can do some tricky JS to ping on and off, you can add even more JS that will try to alert the db when the user navigates away from the page - but at the end of the day, you cannot do anything if a browser is closed unexpectedly, or if that user loses power, or network.
On top of that web browsing is by default stateless and doesn't maintain a connection to the user after the server has finished sending code. The best we can efficiently do is update a table when the user does something new and assume they will be around for a few minutes at least.
I haven't checked but Twitter and Facebook most likely have Javascript code which notifies the server when somebody closes the page, probably coupled with a periodic heartbeat and timeout.
Check the onunload event and XMLHTTPRequest to see how you can make a request to your PHP application notifying of an user leaving (a library like jQuery might help you do this much more easily).
Add a field "last_visit" to user's Table and update it every time when user visit your site
When user login to your site find "last_visit" time and current time,after that use this function
$time_period = floor(round(abs($current_time - $last_visit)/60,2));
if ($time_period <= 10)
$online_offline_status = 1;
else
$online_offline_status = 0;
}
and then print your final result
<?php if (
$online_offline_status == 0){ ?>
<span style="color:#FF0000;">Offline</span>
<?php } else if ($online_offline_status == 1) {?>
<span style="color:#669900;">Online</span>
<?php }?>

How to monitor users in forum page

Is there a way to monitor a users activities in a particular web page? What I want to do is to see if a particular user is currently active in a forum, and if not active, the user should be displayed as absent from forum
$sql = "SELECT * FROM forumlog WHERE user_id = ".$_SESSION['user_id'];
$result = mysql_query($sql) or die(mysql_error());
if(mysql_num_rows($result) == 0){
$sql = "INSERT INTO forumlog (course_id, user_id, log_time)
VALUES(
".$_GET['course_id'].",
".$_SESSION['user_id'].",
".time().")";
$result = mysql_query($sql) or die(mysql_error());
}
The above code is what I use to log the user into the forum, this is because the forum is just a page on my site, and until the user clicks on the forum link he would not be logged in, but then I don't how to go about logging out the user from the forum page or checking to see if the user is active in that forum
When user enters page you can put the time in database. Everytime he refreshes page you should update this time.
To check which users are active you must select from database users that "time" is less than 5 minutes.
To check what users are absent you need to check users than time is greater than 5 minutes.
5 minutes of course can be changed to value you want.
If you want to be more particular you can name actions on your website and put it to database in structure like:
id, user_id, datetime, action, params
and put records
1, NOW(), 4, "viewforum", "forum_id=4,post_id=6"
and then you can select activites in last 5 minutes and check by user_id who is online.
You can do it like this, have a last_seen column in your DB, probably users column
Now Log the login activity of the user, when user switch between forum pages, keep updating the last_seen column, now to detect whether the user is online or offline you need to subtract the last_seen time from current time
if(strtotime($current_time) - strtotime($last_seen) < 60) { //60 Seconds /1 minute
echo 'User Is Online';
} else {
echo 'User Is Offline';
}
/* This will mark users online if they
were active before a minute, certainly you can extend it to 2-3 minutes
i.e 120/180 sec */
The traditional way of doing this has already been explained (updating the "last_activity" field every time the user loads some content).
I'm going to point a totally different way of doing this: websockets.
As you know http works in a request-response way. Connection is created by the client, and closed after a response has been sent (well, not always, depending on keepalive). So your problem ("how can I know if the user is still there?") just can't be solved unless you accept this: "if the user is not requesting more content, consider he's not online anymore".
Well, websockets have an advantage here, as the connection is not closed until the client or the server decide it's time to disconnect. So you can open a connection when the user enters the forum, and leave it there until the client leaves the page or closes the browser and thus the connection is closed.
The bad news: you have to write a server that listens for those connections. For example using Node.js. It's not difficult, but you need root access to the server, and then write a few lines of code.
The traditional way is easier, it's just an sql query, but it's good to know about alternatives.
edit
Quick example
Install Node.js: http://nodejs.org/
Install socket.io (it's a node.js module): http://socket.io/
Write a simple server like this:
var socketsConnected = 0;
var io = require('socket.io').listen(8080);
io.sockets.on('connection', function (socket) {
socketsConnected++;
// send him some information
socket.emit('totalSocketsOnline', { counter: socketsConnected });
// let the others know that the counter has changed!
socket.broadcast.emit('totalSocketsOnline', { counter: socketsConnected });
// socket events
socket.on('disconnect', function () {
console.log("Socket disconnected");
socketsConnected--;
// again, notify all clients!
socket.broadcast.emit('totalSocketsOnline', { counter: socketsConnected });
});
});
4- Write a simple client like this:
<script src="http://yourdomain.com:8080/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://yourdomain.com:8080');
socket.on('connect', function (data) {
// connected, we are so happy...
});
socket.on('totalSocketsOnline', function (data) {
// wohohoo lets show how many sockets we have online now
alert("We have "+data['counter']+" sockets online now!");
});
</script>
I've just coded that, so it will probably contain errors and won't work, but it's a place to start.
If you could go through a little stress you could make an open connection to the server using polling, and return an array position of the mouse for a span of 30 seconds, if the position remains the same with previous 30 seconds then you would conclude the user is not currently active. and could make a script to log the user out..... well, am just saying....

How to handle user online status when he/she close the browser?

I am having table to track user online status by setting 'is_online' field to 1. Now User get logged in the site and shut down his/her system or power down at that time he/she logged in.
Here in database 'is_login' has the value '1' which means he is still using the site.
So I have to do some logic to change that value to '0'.
How can i handle this situation using PHP ?
The normal solution is to store a timestamp in the table which you update every time the user does something. Users with a recent timestamp (say, five minutes) are shown as logged in, everybody else are logged out.
It doesn't even have to be updated on every page load. Keep a timestamp in the session with the last update time as well, and only update the table when the database flag are about to expire.
Store an time-since-last-activity. When it's been longer then a specified time - treat as if offline. You should replace the is_online with an DateTime field, and update it every time the logged in user visits the website.
On the place you want to select all online users, instead of :
SELECT * FROM users WHERE is_online = 1
You could use:
SELECT * FROM users WHERE is_online >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)
you can't. HTTP closes the connection once the page has been delivered. On the server side alone all you could do is checking if a user has requested a page within a certain amount of time.
JavaScript might be your friend. You could use it to create a ping to a php script which then updates the last request timestamp. Once there is no more pinging, the user is gone and you'd know.
If you have trouble with javaScript, a good point to start would be here: http://www.w3schools.com/JS/
You might want to focus on the AJAX and HTTP request stuff.
cu
Roman
You can use jquery to update your site each X time, so a function is executed each 10 seconds, as following code:
function updateTheBBDD(){
... calling mysql_connect -> mysql_insert -> mysql_close
}
setInterval("updateTheBBDD()",10000);
Also, when painting the user status monitor instead of consulting the BD and:
1->green
0->red
You should:
actual - time > 10 ---> red
actual - time <= 10 ---> green
Due to the stateless nature of the web it is not possible to know exactly when the user left your website. So you can't really trigger any code to change the mentioned value.
As the other have said one has to store the time-since-last-activity to get an approximate idea when was the last time the user was actually doing something with the website.
HTH :)

Online Listing problem - Chat in php

I have to identify the online users
The condition is when a user close the window, he/she will be removed automatically from online list.
the List is being generated on the base of session value.
any one please help me.........
its difficult to store a flag on the close window event. what if the user closes the browser of shuts down the system directly?
you can achieve approximately the same thing by storing a unix timestamp in the database every time the user does some activity (also including page refreshes ).
The to see whether the user is online, add a certain amount to time to this timestamp and compare the value with current time stamp.
For eg. lets say we decide to consider a user online if there is some activity in past 10 mins
$online = ($last_active_time + 600 > time()) ? True : False;
<script type="text/javascript">
window.onclose = function()
{
// use jquery to make an ajax post to your chats controller, telling it someone has signed off.
// CURRENT_USER_ID will have to be passed from your application to JS, or you could try to read your session cookie there...maybe
$.post('/chats/signed_off', {user_id: CURRENT_USER_ID});
}
</script>
That's the logic. The implementation will be specific to your application, which we don't know anything about.

jquery - refresh the page when new data stored in to the table across the browser sessions

Environment : PHP/MySQL/Jquery
I would like to refresh the page (ex: index.php) when new data stores in to the table (ex : new_entry_table) checking for every one minute. The same page will be opened in many machines(pc-browsers) at a time all should get refresh when new data arises.
using jquery and database check i tried the following:
setInterval(function(){
$.post("new_data_check.php", function(data) {
if(data > 0){
$("#container").fadeOut('fast').load(location.reload());
}
});
return false;
},60000);
new_data_check.php: : checks
for new data in the test_db where
newdata_field=0 ; : If any new
data arises echo "1"; And update the
newdata_field=1; to stop constantly
refreshing the page. : else echo
"0"; : Just for a trigger
So the above jquery code checks new_data_check.php every 1 min for the trigger , if any trigger arises it will refresh the container.But its getting refresh only one opened session other opened sessions(in other browser or other pc) not getting refreshed.
Suggest a better way to do this. Thanks.
Your new_data_check.php file will need to keep track of all the users that are independently viewing the page.
If not, this will happen:
User 1 and User 2 are both logged into the site.
User 1 does the check 5 seconds before User 1, there is new data.
User 1 completes his request. The server clears the new_data bit.
User 2's request arrives 5 second later. Hedoes his request, but at this point, User 1 has set the new_data field to 0. His data is stale, but User 1 has effectively co-opted him.
By the looks of it, you're not supplying it with any information that would identify the user - unless the server is determining that using the IP address. If that's the case, remember that it's likely everyone behind a small network is going to have the same external ip address. So it can't tell people at an office apart.
What you could do is generate some kind of unique hash for each session and pass that off to the browser. The javascript can then provide the php script that same token.
Another solution without any sort of special bit, would be to pass along a timestamp with the request. Essentially, the client says "my latest bit of data arrived at 9:21:53 PM" The server then checks and responds "My most recent data was created before that, so you're still good. " or "I've got something that was created or modified on 9:22:53PM, you should download it."
With that method, you don't need to worry about who's who. Instead, you need to have modification/creation times on the data you're checking for staleness. You also need to make sure that the clients clock is synchronized correctly - better yet, don't trust the clients date and time information. Maybe utilize your new_data_check.php to provide the script with a timestamp it can pass along on subsequent requests.

Categories