Pure, serve开发者_开发问答r-side PHP. Every time a user submits a form, I update a 'last activity' time in the database.
I want to make a periodic check and force logout inactive users to free up licenses.
How would I do that? Should I also store the session Id in the database and then destroy the session? That would free up a license for another user and when the first finally submits another form I can check at the top of each form action file if the session still exists and redirect the user to the login page if necessary.
Would that work? is it the 'best' way? Any example code?
Update: I am polling because I need to know when the user timesout in order to update the database.
With each login, you need to keep track of the Session Start Time, which can be done like this:
$_SESSION['SessionStartTime'] = time();
With each user request to perform any operation, you need to run this script to monitor inactivity.
<?php
session_start();
$TimeOutMinutes = 15; // This is your TimeOut period in minutes
$LogOff_URL = "login.php"; // If timed out, it will be redirected to this page
$TimeOutSeconds = $TimeOutMinutes * 60; // TimeOut in Seconds
if (isset($_SESSION['SessionStartTime'])) {
$InActiveTime = time() - $_SESSION['SessionStartTime'];
if ($InActiveTime >= $TimeOutSeconds) {
session_destroy();
header("Location: $LogOff_URL");
}
}
$_SESSION['SessionStartTime'] = time();
?>
This problem is more difficult than it seems on the surface.
You need to consider the session behavior at three different levels:
- PHP
- database
- browser
PHP
For PHP, you'll need to set the session timeout to whatever you limit is. Here's some example code from php.net:
<?php
session_cache_limiter('private');
/* set the cache expire to 30 minutes */
session_cache_expire(30);
session_start();
?>
Database
Sounds like you need to keep track of how many sessions are active so you can enforce your license. Since you're in PHP, you'll need to do this at the database level. Each request could write a "last request time" for the user (UPDATE users SET last_access=NOW() WHERE user_id=?
), and then you can surmise that active sessions are the ones within the last 30 minutes.
Rather than "last access time", you can try to keep track of the active sessions, again in the database. I'm not exactly sure how this is best done in PHP. I think you can patch into the PHP's session deletion code. I believe it's possible to have it call a function when a session expires, but I haven't done this.
Browser
Javascript polling can be used, but is not necessary, as long as you have a server side timeout. Consider cases where the user turns off Javascript, or you have some Javascript error that causes script to stop running.
We have a very Ajax intensive site, so Javascript is important. A timeout might be discovered when the user does something as innocuous as open a panel on a page. I wrote up my recent experience here.
I want to make a periodic check and force logout inactive users to free up licenses
I assume you meant.. When a session has (should have) expired, you need to 'do something' to free a license, and you want it controlled server-side.
session.gc_maxlifetime hurts here because PHP does not send notification when it destroys a session.
You need a cron job to scan the PHP session folder for sessions whose atime has exceeded your timeout and release their license (and also delete the session). A beginning for such a script is
cd /path/to/sessions; find -cmin +24 | xargs rm
which was taken from the bottom of http://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime You will replace the xargs rm with something more useful to you.
You can do this purely using JavaScript. Start an count down timer. Then wait for activity and reset this timer. If there is no activity and timer goes off, you can call your logoff sequence.
for Example :
<body onmousemove="reset_interval()" onclick="reset_interval()" onkeypress="reset_interval()" onscroll="reset_interval()">
<script type="text/javascript">
function set_interval(){
//the interval 'timer' is set as soon as the page loads
timer=setInterval("auto_logout()",10000);
// the figure '10000' above indicates how many milliseconds the timer be set to.
//Eg: to set it to 5 mins, calculate 5min= 5x60=300 sec = 300,000 millisec.So set it to 3000000
}
function reset_interval(){
//resets the timer. The timer is reset on each of the below events:
// 1. mousemove 2. mouseclick 3. key press 4. scroliing
//first step: clear the existing timer
clearInterval(timer);
//second step: implement the timer again
timer=setInterval("auto_logout()",10000);
..completed the reset of the timer
}
function auto_logout(){
//this function will redirect the user to the logout script
window.location="your_logout_script_location_here";
}
</script>
Hope that helps.
PS: Reference from: http://www.w3hobbyist.com/web-designing/auto-logout-after-some-time-of-inactivity-with-javascript/
All these solutions are interesting and work well.
But: What if you are in a frame-based content window?
Then there are two options:
Before logging out or calling the logout script, the frame-based top of the page must be reached (can be done using a JavaScript command "unnestling" the depth of the current position within the frame)
Alternatively, a frame buster oder frame killer script can be invoked to reset to the top's position such as
<style> html{display : none ; } </style>
<script>
if( self == top ) {
document.documentElement.style.display = 'block' ;
} else {
top.location = self.location ;
}
</script>
(c. o. WikiPedia: http://en.wikipedia.org/wiki/Framekiller)
More about frame busters and frame killers can be read from various sources by a simple Internet search for "framebuster" or "framekiller".
Here is my version based directly on the answer by RKh.
This version will re-set the timer IF the session hasn't timed out yet. So you can paste this whole block right underneath your session_start() and you don't have to call it separately every time a user makes a request to perform an action.
/* Control Session Timeout */
if (!isset($_SESSION['LastActivity'])) {
$_SESSION['LastActivity'] = time();
}
//Set Timeout Window in Minutes
$TimeOutMinutes = 5;
//TimeOut in Seconds
$TimeOutSeconds = $TimeOutMinutes * 60;
if (isset($_SESSION['LastActivity'])) {
$InactiveTime = time() - $_SESSION['LastActivity'];
//If Inactive Time more than timeout value log the user out
if ($InactiveTime >= $TimeOutSeconds) {
session_destroy();
header("Location: $baseURL");
}
//If Inactive Time less than timeout reset the last activity to current time
elseif ($InactiveTime < $TimeOutSeconds) {
$_SESSION['LastActivity'] = time();
}
}
I got this simple solution using jQuery.
var idleTime = 0;
var start = new Date();
var end;
// if mousemove, a keypressed or a mouse click events fired
$(document).on('mousemove keydown click', function() {
end = new Date();
idleTime = (end.getTime() - start.getTime()) /1000;
// 30 seconds of idle time
if ( idleTime > 30 ) {
// logout/endsession code here
//window.location.href="logout.php";
}
});
Best Regards.
精彩评论