RSS 2.0 | Atom 1.0 | CDF

Search

Categories

Archive

Blogroll

Sign In

# Thursday, February 19, 2009
Thursday, February 19, 2009 4:18:50 PM (GMT Standard Time, UTC+00:00) ( Asp.Net )
today i came across a situation where a user was spending a long time filling out a form.  they went past the session timeout and when they hit save they got booted back to the login screen, having lost the previous 30 minutes of work.  i looked around the net and found a few options with AJAX and what not but it doesn't make sense to keep renewing the session automatically otherwise you might as well not have a timeout, which is there for security reasons anyway.  in my case i don't actually want to save the information to the database (it's a transaction) until the user hits the Save button, i just want to keep the session alive. 

so i came up with this idea to ask the user if they want to keep their session alive with a javascript prompt every 15 minutes. if they leave their computer and don't answer the prompt, the session will time out since they won't have interacted with the web site (regardless of how they answer the prompt after the timeout).  if they answer OK to the prompt it invokes a Ping() type web service to keep the session alive.  this is the most lightweight way i could think of doing it.  i don't want to post back to the page because that will interrupt the user and make them wait for the page to reload.

there are 3 parts:

"KeepAlive" function

I put this function in a 'Util' class so pages can easily turn on the 'Keep Alive' functionality, simply call Util.KeepAlive(this);

public static void KeepAlive(Page p)
{
p.ClientScript.RegisterClientScriptInclude("KeepAlive", "/KeepAlive.js");
}

Ping.asmx (add the web service to your root folder)

[WebMethod]
public void Ping()
{
HttpContext.Current.Response.Write("OK");
HttpContext.Current.Response.End(); // this makes the result easier to parse than an XML web service message
}

KeepAlive.js (put this file in your root folder)

var timerID = 0;	     // used to track the timer function
var interval = 1000*60*15; // 15 mins
var KeepAliveUrl = '/Ping.asmx/Ping'; // replace your web service address here
var xmlhttpKeepAlive;

function AutoSaveSubmit()
{
if(confirm('15 minutes of idle time has passed, do you want to keep your session active?'))
InvokeWebService();
}

function InvokeWebService()
{
if (window.XMLHttpRequest)
{
xmlhttpKeepAlive=new XMLHttpRequest();
xmlhttpKeepAlive.onreadystatechange = xmlhttpChangeKeepAlive;
xmlhttpKeepAlive.open('GET',KeepAliveUrl + '?T=' + timerID,true);
xmlhttpKeepAlive.send(null);
}
// code for IE
else if (window.ActiveXObject)
{
xmlhttpKeepAlive=new ActiveXObject('Microsoft.XMLHTTP')
if (xmlhttp)
{
xmlhttpKeepAlive.onreadystatechange = xmlhttpChangeKeepAlive;
xmlhttpKeepAlive.open('GET', KeepAliveUrl + '?T=' + timerID, true);
xmlhttpKeepAlive.send();
}
}
return false;
}

function xmlhttpChangeKeepAlive()
{
var text;
if (xmlhttpKeepAlive.readyState == 4)
{
text = xmlhttpKeepAlive.responseText;
if (xmlhttpKeepAlive.status==200) // OK
{
if(text == 'OK') // reset the timer
timerID = setTimeout('AutoSaveSubmit()', interval);
else
alert('Your session has already expired.\nIf you have any information on this page you will lose it if you try to save this page now. You have 2 options to avoid losing the information on this screen.\n\nOption 1: open a new internet window and log in again to the web site, then close that window and go back to this window, at which point you will have a new session and you will be able to save the information.\n\nOption 2: Copy all the text you have typed on this page and paste it into another program (such as Word or Notepad), then log in to the web site again (click the home page) and come back to this page, and paste in the text again.\n\nTo prevent this happening in the future, click OK on the 15 minute reminder box each time it appears, this will keep your session active. If you do not answer the reminder within 10 minutes the session may expire.');
}
else
alert('Error: ' + xmlhttpKeepAlive.status + '. The session may have already expired, please try to save the page now');
}
}
window.setTimeout('AutoSaveSubmit()',interval);

You might be wondering why i append the timer code/number to the url of the web service.  The reason is because IE has a caching bug and will not actually send the XmlHttp request unless the URL is different to what it has in its history, it will just return the previous result.

Comments [6] | | # 
Tuesday, March 24, 2009 4:52:13 PM (GMT Standard Time, UTC+00:00)
Hi, this works great. I have been searching all day looking at various examples and ways on how to implement a keep-alive but this is the best one I have found. I am using this on my web based application for Administrators be keep logged in until they log out.

Nice one!
Garry Grimshaw
Tuesday, March 24, 2009 5:02:56 PM (GMT Standard Time, UTC+00:00)
hi gary, glad you found it useful!
tim
Monday, August 03, 2009 1:17:11 PM (GMT Daylight Time, UTC+01:00)
awsome, lightweight and versatile
Brendan Saunders
Friday, October 30, 2009 8:50:59 PM (GMT Standard Time, UTC+00:00)
If you set-up a javascript timer to fire 30 seconds before the session timeout, wouldn't it
automatically reset the timeout period? This seems like a simpler solution.

If you want to alert the user, just popup an alert first.
Clyde
Sunday, November 01, 2009 1:21:15 PM (GMT Standard Time, UTC+00:00)
hi clyde. the point of this is not to automatically reset the timer, in which case you should just set a very large timeout and not require any javascript at all. in this case we want to keep a reasonably short session timeout, but prevent the user from losing unsaved information if they stay on the same page for a long time. if you re-read the article this is explained.
best
tim
tim
Tuesday, April 26, 2011 9:59:38 AM (GMT Daylight Time, UTC+01:00)
HI ,,
thanks for the article.. i was in lot of exploration for the same problem you mentioned above.
Actually i am using asp.net2.0 with vb, so was confused how to use above code since we need to keep in util class?
Please explain how to implement this in vb asp.net2.0

KP
kp
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Live Comment Preview