Clientside Session Timeout’s

There comes a time in web application development that you need to ‘timeout’ idle users. This comes in a variety of ways, here’s a few common reasons that you may desire this activity.

  • Security – you don’t want to leave sensitive data on a users screen when they’ve gone to lunch or left for the day.
  • Server Resources – persisting/keeping an active ‘session’ available on the server takes resources (the exact type varies, but this is usually database, memory or file resources)
  • Server ‘enforced’ session timeout’s and the potential errors and lost data experienced by the users in that circumstance.

My personal approach to this has evolved over time, here’s a brief synopsis:

  1. Use standard server-side session timeout, often leading to a bad user experience when they loose data on a form submit.
  2. Use META REFRESH…where timeout is in seconds, in this example it’s 60 seconds (1 minute).
    <meta http-equiv="refresh" content="60;url=http://www.giantgeek.com/" />
  3. Use javascript 'timeout' (problem is that this is not 'measureable')
    
    <script type="text/javascript">
    setTimeout("javascript:myTimeout();",minutes*60000); // code minutes
    </script>
  4. Use javascript countdown timer and custom code event.

<html>
<head>
<title>Timeout example</title>
<script type=”text/javascript”>
var build=’testing’;
var timerID = 0;
var loadTime = null;
var stopTime = null;
function xload(){
loadTime=grvMillis();
grvWindowStatus(build);
grvSetTimeout();
}
function xclose(){
grvWindowStatus(”);
}
function grvMillis(){
return new Date().getTime();
}
// Start timer
function grvTimerUpdate(){
timerID = grvTimerClear(timerID);
if(loadTime == null){
loadTime=grvMillis();// Start Time
}
// Calculate Current Time in seconds
var timeNow = grvMillis();

var think = calcMinSec( calcTimeDiff(timeNow,loadTime) );
var remain = calcMinSec( calcTimeDiff(stopTime,timeNow) );
grvWindowStatus(build + ” ” + think + ” ” + remain );
timerID = setTimeout(“grvTimerUpdate()”,1000);
}
function calcMinSec(diff){
var mm = removeDecimal(diff/60);
var ss = zeroPad(removeDecimal(diff-(mm*60)),2);
return (mm + “:” + ss);
}
function calcTimeDiff(tmpStart,tmpStop){
var diff = (tmpStart – tmpStop)/1000;
return diff;
}
function removeDecimal(val){
var rc=””;
val = val + “”;
if(val!=””){
var pos = val.indexOf(“.”);
if(pos > -1){
rc=val.substr(0,val.indexOf(“.”));
} else {
rc=val;
}
}
return rc;
}
function zeroPad(x,sz){
x = x + “”;
while(x.length < sz){
x = “0” + x;
}
return x;
}
function grvTimerClear(x){ // this clears a timer from the queue
if(x){
clearTimeout(x);
x = 0;
}
return x;
}
function grvSetTimeout(){
var min=45; xID=grvTimeout(“javascript:grvTimeoutUSER()”,min); // EXAMPLE: this could be conditional!
stopTime = grvCalculateTimeout(min);
grvTimerUpdate();
}
function grvCalculateTimeout(mins){
var timeNow = grvMillis();
var exp = timeNow + (mins*60*1000);
var timeExp = new Date(exp).getTime();
return timeExp;
}
function grvTimeout(x,minutes){ // this sets a timer(request) in a queue
return setTimeout(x,minutes*60000);
}
function grvTimeoutUSER(){
alert(‘Session Inactivity Timeout [USER]’);
// DO WHAT YOU NEED TO HERE!}
function grvWindowStatus(txt){
window.defaultStatus=txt;
}
</script>
</head>
<body onunload=”xclose();” onload=”xload();”>
</body>
</html>

Another benefit of this last solution is that you also have access to the user “Think Time” and can therefore measure how long the user spends on a given page.

Cheers!

Leave a Reply