Monday, September 13, 2010

How To Keep ASP.NET Session Alive

If visitor doesn't make any web request in time interval longer than specified as session timeout (20 minutes by default), session will expire. That means all session variables will be deleted. Sometimes, we want to keep session alive and wait while user is completing some long task.


Although it is possible to increase session timeout (see ASP.NET session timeout and expiration tutorial), this is not scalable option. every session variable requires some memory on server. If website has many visitors and a lot of session variables, increasing of timeout too much could spend all available memory and decrease website performances. If session timeout is increased, server will keep all sessions, including unimportant sessions from visitors who leaved website. As better solution, you can make periodical requests from client side, which will keep session alive only if browser is still showing your page. In that purpose, we can use JavaScript, jQuery, Meta Refresh or ASP.NET Ajax

How to keep ASP.NET session alive using JavaScript
ASP.NET just remembers time of last request and it doesn't know if visitor is closed browser window or is just doing something else and will return soon. It is certainly worthless to keep session values of user who leaved website. It would be better if we could keep live sessions of visitors who still have page opened.

Solution for this is to use JavaScript that will make periodic calls to some .aspx page on website, restart session timeout and keep session alive in that way. Implementation code will use JavaScript setInterval function. It could look like this:

<%--
In this example, image will be used to keep session alive,
By changing image's src parameter, we'll make periodical requests
to web server.
--%>





In this example, RefreshSessionState.aspx page will be called every minute. This is far less than default session timeout which is 20 minutes. If you just want to keep session alive, you can set this time for 19 minutes (19 * 60 * 1000 = 1140000).

But, with smaller intervals you could know almost instantly when visitor is closed a browser. If scalability is a problem, you can delete session variables almost immediately after user closed web browser. There is no need to wait 20 minutes for session to expire. You can even decrease session timeout to low value, like 2 minutes. JavaScript from previous example will make requests every minute, and keep sessions alive for active users (users that have opened web browser), but sessions where browser is closed will expire.

Since RefreshSessionState.aspx page is called every minute, you can use ASP.NET server side code for tasks like visitor tracking, how many visitors are currently online, which page each visitor is currently browsing etc.

This option will work fine, although it has its own small drawbacks. Some users could have JavaScript disabled or have a browser that doesn't support JavaScript (like some mobile web browsers). If JavaScript is not enabled, this code would not work and session will expire. Also, rarely but theoretically possible, especially on mobile browsers is, if user's Internet connection is temporally broken JavaScript will miss few requests while user is reconnecting.

This example manipulates image's src element to make request to web server. There is a second option to make web requests in JavaScript using Http Request, but this option requires browser specific code because Internet Explorer and Firefox use different objects. IE uses ActiveX object Msxml2.XMLHTTP or Microsoft.XMLHTTP, while Firefox uses XMLHttpRequest. So, final browser compatible code becomes large. In the other hand, using image's src property to make request requires

As very similar alternative we can use jQuery for same task. In this example, I will use jQuery post function to make a request to web server. Pages requested with POST are not cached, so we don't need unique URL like in previous JavaScript example.

Code for keeping ASP.NET session alive using jQuery is very short:




Keep ASP.NET session alive using Meta Refresh
One more way to keep ASP.NET session alive is by using Meta Refresh and postback. Of course, we can't refresh complete page because that will annoy visitor, especially if he or she is completing a large form. Instead of that, place small IFRAME tag somewhere on page, and set its src parameter to helper .aspx page. Let's call that page RefreshSessionState.aspx.

HTML code on main page will be: