How to monitor users in forum page - php

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....

Related

PHP SESSION destroy when user close the browser or automatic session destroy

I have a hole in my login-logout script and i really have no idea how to fill it.
The whole problem appeared when users started to simply leave the page instead of logging out. There actually wouldn't be anything bad about it, because in my code there is logout after 15 minutes(session time out), but in my database there is a column "online" which is changed on login and logout, so when user just close the page it doesn't change to offline.
I was trying window.onbeforeunload to href to page where the logout is (didn't work)
I have heared also about cron but i have completly no idea how to do this.
Can anyone tell me how to solve my problem with detailed explanation?
Looking forward to hearing from you.
A solution could be that each time the page loads or perhaps an ajax request for each page to bounce a code to the server to say "hey, this user is online", and then have a built in function to your scripts (that work on any page, anyone views) to check if the mysql update time is within the last X minutes and if not the user is assumed to have logged out.
I think I've explained that quite badly.
You have a timestamp field in your Table - associated with each user logged in, and they're deemed to be online if the timestamp last update is within X minutes of NOW,
So, each time a page is loaded or each time an ajax call is processed, the timstamp field is updated, and then on any field that has timestamp older than X minutes, this is because they've (probably) logged out and so they are changed in the DB to being "offline". Although if they're just busy and still online, perhaps don't actually log them out, just mark them as offline.
I'm running without details on how you process your database content details etc., so my idea might be well out from what you can create - ?
EDIT:
Ajax Suggestion
For ajax to act on each page every X seconds, write the following ajax onto the page the member is on, be aware that the number at the end is milliseconds, 600000 = 10 minutes. So used 500000 as it's within the timescope. so the ajax function runs every 8.5 minutes, or on page load.
THe ajax is quite poorly written and probably can be improved. But should work. You'll need to research a more optimal ajax script.
BROWSER PAGE:
<script src="js/jquery-1.11.1.min.js" type="text/javascript" ></script>
<script type="text/javascript">
$( document ).ready(function() {
var memberId = <?php print $memberId; ?>;
var securityKey = <?php print some security key code or suchlike to validate this ajax at the otherend;?>;
setInterval(function(){
$.post("/ajaxSession.php",{
MemberId: memberId,
somesecuritykey: securityKey
});
}, 500000);
});
</script>
AJAX PAGE:
Please note update time in this case is a 'timestamp' MySQL field.
<?php
/**
Setup this page as if any other PHP page but this page will never show to the browser,
AJAX data is supplied as $_POST and inn this case $_POST['somesecuritykey'] and $_POST['MemberId']
**/
session_start();
/**
include classes and files
**/
if (is_numeric($_POST['MemberId'])){
$memid= (int)$_POST['MemberId'];
/**Also include your security stuff here **/
$sql = "UPDATE Members SET UpdateTime = NOW() , LoggedIn = 'YES' WHERE MemberId = ? LIMIT 1"
$mysqli = new mysqli();
$mysqli->prepare($sql);
$mysqli->bind_param("i",$memid);
$mysqli->execute();
}
And that should keep the timestamp values upto date, so logged in people is anyone whose UpdateTime is MORE than time()-601 (10:01 minutes), SQL listings can change this on any header/class which occurs when anyone access any page
SQL = "UPDATE Members SET LoggedIn = 'NO' WHERE UpdateTime < (NOW() - INTERVAL 10 MINUTE)"

Forum Current Online users

I have my own forum script in PHP (Yii2 Actually) and I want to show online users.
It would be easy if users would be active up until they log out. But that is not the case. Most of the time user leave their machines logged in but they are not active. Here I could use time limit (renewing time with each request and deleting those which are past that time limit) but isn't that overkill?
Is there any popular/better way of monitoring online users in the forum?
One possible way is to intercept user interface events in javascript and send an ajax notification to the server that the user is still there. Of course, this should be buffered, so that you don't get flooded with requests when the user moves the mouse. Something along the lines of
$('body').on('keydown mousemove scroll', function() {
clearTimeout(notifyTimer);
notifyTimer = setTimeout(function() {
$.get('my-server.com/user-is-active');
}, 60 * 1000);
});
On the server side, update the last-active field in the users table with the current timestamp. When displaying online users, select those with last-active > now - 15 min.

Changing user status

I have a logging system on my site, but I don't know how to get a user's status (online/offline). I've read more themes, but I don't understand them... can someone give me an example?
You don't know if the page is close from the server, you can't check that with PHP.
You can check with javascript on client side and call your server in ajax on each events.
For exemple with Jquery :
<script>
$(window).unload( function () { $.get('http://exemple.com/user.php?offline=true'); } );
</script>
Just add an column status in your user_info table in database and when user logs-in then update it with 'loged-in' and when it logs out then update it with 'Logs-out'
I'd keep track of the user's actions; this is what Stack Overflow does (along with "last seen" instead of "online" or "offline") and it works very nicely.
Pick a criterion:
Requested a page
Posted something
Whatever else applies to your website in particular
If the user hasn't done that in the last n minutes, then you can assume the user is offline. I'd say a good threshold is probably 30 minutes.

timed auto logout and browser close

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.

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.

Categories