I am exploring a potential in-house content delivery system where we have to keep track of student time-on-task. As long as the student is interacting with the page, there is no problem. If the student goes out for lunch leaving the page open, the session should time-out and they will not get credit for their on-line time after the timeout.
I already figure I can easily capture events like navigating away from a page and recording that fact with PHP into the student's record in MySQL, but what is the best way to time a student out? JavaScript? I looked around and haven't found a good explanation yet.
Thanks for any help!
---------- EDIT --------------
After Floris' suggestion about looking at a particular post about idleness, most suggested a JQuery solution, but one poster had a simple solution with no JQuery. Does this code seem like it will work? It looks fine to me:
var inactivityTime = function () {
var t;
window.onload = resetTimer;
document.onmousemove = resetTimer;
document.onkeypress = resetTimer;
function logout() {
alert("You are now logged out.")
//location.href = 'logout.php'
}
function resetTimer() {
clearTimeout(t);
t = setTimeout(logout, 3000)
// 1000 milisec = 1 sec
}
};
Use JavaScript to detect when a user becomes idle. When a user become idle fire an AJAX call that blows away any cookies or session data.
A student can easily fake it, if you let the browser do the work. Instead I'd turn it around and log whenever a user does an action (like go to a different page). The time spend is the sum of the time between an action and the next (delta time), but exclude if delta time is bigger than 15 minutes.
Related
Good day folks - be gentle - I'm a first time poster.
I have a page on a php-based web site that uses an AJAX-based call to update a DIV tag with a table of data every 5 or 10 seconds. The security folks where I work want me to make sure users get logged out after 15 minutes of inactivity.
To that end I put in
<script type="text/javascript">
window.setTimeout("location=('/mysite/session_timeout.php');",900000);
</script>
The problem is, of course, that the AJAX refresh of the table is 'resetting' the timeout counter ...
So my question is basically "Is there a client-side way to either mitigate the ajax call resetting the clock so to speak, or do I need to address this with php's _SESSION array and hide values in there, or does someone have something better than that?"
Thanks for any help you all can provide.
You can Store the start time of that page and update you table data without reloading the page. and check for the start time and destroy session accordingly.
You can try something like this
$_SESSION['activity'] = time();
function check_if_logged_in() {
if(time() - $_SESSION['activity'] > 900) {
// Do redirect or take other action here
}
}
Or you can use this jQuery plugin.
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)"
Status as in online/offline..
When a user enters onto a page, it records the current time and puts it in the database.. if 5 minutes passes since their last action, it shows them as offline?
You can use JavaScript to time the five minutes, then use AJAX to call a PHP script that updates the database.
window.onLoad = function(){
setTimeout(UpdateDB,1000*60*5);
}
function UpdateDB(){
// AJAX call...
}
This would be a good way to start. You can easily check the period of inactivity.
It would be relatively simple for you to set up an AJAX ping to your server on a long interval~ so that as long as the user's browser has your site loaded, it's still pinging it's status as online.
I have a simple chat client set up that allows users to login with a username and stores the messages they write in an sql database. Every 3 seconds, the database simply prints of all the rows. So it's basically a chat client.
I'd like to keep a list of who's online. How can I do this? How can I sense when someone has closed the browser?
Right now I'm pulling the username as
$name = $_COOKIE["name"];
and if this value is empty, I know they left. But once they left, it's too late to know what their username was so I can't keep track of who exactly left.
Ideas? I'm fairly new to php, javascript, and html, so keep that in mind :)
It is hard to send a last request to the server when someone closes the window, since Browsers usually don't wait for JS execution to finish when the user wants the window closed (as is the case with onbeforeunload).
Whenever I am confronted with a situation like this, I tend to use onbeforeunload to send a final request (which happens fast and usually finishes before browser window is closed), but also implement a timeout feature. The timeout feature would work as follows:
Everytime the user sends something to the server, the server recognizes this as 'still there'. At the same time, the client sets a timer of, say, 45 seconds. If the user does not type anything for 45 seconds, the client sends a 'still alive' signal on its own to stay connected.
Now, the server should execute a removeInactive() routine every 60 seconds (allow 15 seconds slow-connection margin, hence the 45/60 seconds) which removes any users who haven't sent a 'still alive' signal in the last 60 seconds.
This system worked fine for me so far, you could try it out for yourself.
Assuming your using AJAX to pull in the chat messages every X seconds, update your table of users at the time with the current timestamp for that user. Then anyone who has a timestamp say older than 10 seconds, you will know they have left the page.
put online users in a table that will have a field named like 'lastSeen' update this field every few seconds with ajax call..
ajax call be made someting like this :
window.setInterval(function() {
$.ajax({
url: _URL_ENGINE + "/updateLastSeen/?userid=" + userID,
success: function(data) {
}
});
}, 2000); // 2000 means 2 seconds
now to query the list of online players u can query them like
select * from players WHERE lastSeen > DATE_SUB(NOW(), interval 40 SECOND)
hope this helps
Use the onbeforeunload event.
You could possibly attach to the onunload event in javascript. Have a look at http://help.dottoro.com/ljflhicd.php for full details.
Refer these links. Sure this is a light for ur darkness.
Link1:
http://www.daniweb.com/forums/thread252828.html
Link2:
http://phpeasystep.com/phptu/9.html
I want to implement a basic login system in some PHP app where no cookies will be involved. I mean, the user closes the browser and the login expires, it will remain active during the browser session (or if the user explicitly logs out) otherwise.
I want to log all this activity and I'm thinking that every time the user refreshes the page, opens a different link or logs out, I record that time as the last access made by that user, overwriting the previous access log.
But my problem is when and how should I insert another record into the database instead of overwriting the last one?
Should I just define a timeout and if the last access was made above that timeout, another log should be inserted into the database? Should the session expire too after that timeout?
Or is there a better way?
Ideally, I would like to log the "log out action" when the browser was closed, but I don't think there's a way to detect that is there?
Suggestions?
The real problem here is another. Why do you need this? I mean. It seems to me very easy:
You take all your website page and add at the firsts lines something like session::recordAction() and inside that method you connect to the database and record the timestamp coming from time() which is a native function. It doesn't really matter where you are going to place that field in the database since it's based on your design preferences and schema.
When you want to know if a user had been online in the last, let's say, 10 minutes you can compare the 2 timestamps (the one you recorded in the database and time()) and say something like:
if (session::getLastAction() < 10 * $minute) { /* Do some cool stuff here */ }
If you are recording action log due to recover them in case of security issues or something, you have to remember that that timestamp means the last time a user refreshed a page. And in this case i'd suggest you to use a .txt file to record them and to record also the i.p. and all the datas you can recover from that user. So you are not overusing database for no reasons.
If you are building this system for others purpose just tell me and i'll let you know how to solve all your problems with this way.
Tips
Remember that pretty nobody actually really press the logout button, they just leave the website. And if they are leaving the website there's no way to actually know that. The fact is that they are not requesting page to the server and it could happens if 1. They have left the website or 2. if they are reading the webpage and didn't refreshed.
Notice
If i didn't got it wrong you are looking for some way to make a login system and you were concerned about cookies:
Cookies expires (by default, using setcookie()) after the browser is closed. You can delete them by setting a past timestamp and you can make them live forever setting a very long date. They are very usefull and are still used by a lot of people.
Sessions expires after 24 or 22 minutes of inactivity (not sure, google it).
I hope i was understandable, if not just ask for clarifications.
:)
Revising my answer here a bit because you already mentioned the server side timeout….
The only thing you can do client side is to use the onbeforeunload event to call the logout page (if the user did not click a link in the document..)
Unfortunately, the browser back, forward, and refresh buttons will cause a logout...
To get around that, have your logout.php (auto logout page) sleep for 20-30 seconds and then check to see if the last impression was under 30-45 seconds ago before logging them out…
Just add this to script tags in the head of your document and change the ‘logout.php’ to whatever you want… * You may also need to edit the window.onload function to correctly add the onclick handlers if you use something other than links to navigate….
var xmlhttp=false; var target; var combo;
/*#cc_on #*/
/*#if (#_jscript_version >= 5)
try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xmlhttp = false; } }
#end #*/
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
xmlhttp = new XMLHttpRequest();
}
var dologout = true;
var logouturl = 'logout.php';
window.onbeforeunload = function() {
if (dologout) {
xmlhttp.open("POST", logouturl, true);
xmlhttp.send(null);
}
}
window.onload = function() {
for (i=0;i<document.links.length;i++)
document.links[i].setAttribute("onclick","dologout = false;");
}
Essentially this just attaches an onclick event to all document.links and changes the 'dologout' flag to false if a document link was clicked...
If the dologout flag is true when the onbeforeunload event fires, it sends a post to the 'logouturl' / 'logout.php' ...
There is no way to trigger an action that will be of value to you when the browser is closed. http://www.webdeveloper.com/forum/showthread.php?t=93810 at this link a user asked a similar question and the problem that he had and I suspect you will have is that every time a user leaves a web page it is considered like they are leaving the site and so this will interfere with you your logging activities. I would just use cookies and make them expire often. Log a users action every time they perform some useful action on your site, ie.. clicking on a link and focus less on how much time they are spending just reading content.