views:

928

answers:

2

What is an easy and unobstrusive way to keep an ASP.NET session alive as long as the user has her browser window open? I think maybe timed AJAX calls? I want to prevent that users keep their window open for a long time, then enter stuff and on submit nothing works because the server side session expired. I don't want to increase the timeout value larger than 10 min on the server as I want closed sessions (by closing the browser window) to time out fast.

Suggestions, code samples?

+8  A: 

I use JQuery to perform a simple AJAX call to a dummy HTTP Handler that does nothing but keeps my Session alive:

function setHeartbeat() {
    setTimeout("heartbeat()", 300000); // every 5 min
}

function heartbeat() {
    $.get(
        "/SessionHeartbeat.ashx",
        null,
        function(data) {
            //$("#heartbeat").show().fadeOut(1000); // just a little "red flash" in the corner :)
            setHeartbeat();
        },
        "json"
    );
}

Session handler can be as simple as:

public class SessionHeartbeatHttpHandler : IHttpHandler, IRequiresSessionState
{
    public bool IsReusable { get { return false; } }

    public void ProcessRequest(HttpContext context)
    {
        context.Session["Heartbeat"] = DateTime.Now;
    }
}

Key is to add IRequiresSessionState otherwise Session won't be available (= null). The handler can of course also return a JSON serialized object if some data should be returned to the calling JavaScript.

Made available through web.config:

<httpHandlers>
    <add verb="GET,HEAD" path="SessionHeartbeat.ashx" validate="false" type="SessionHeartbeatHttpHandler"/>
</httpHandlers>
veggerby
+1 for the cool name
Martin
+1 and +acc for a good solution with code.
Alex
@veggerby "to a dummy HTTP Handler that does nothing but keeps my Session alive".Can you please post sample code of HTTP Handler to keep the session alive?
Gopinath
A: 

Do you really need to keep the session (do you have data in it?) or is it enough to fake this by reinstantiating the session when a request comes in? If the first, use the method above. If the second, try something like using the Session_End event handler.

If you have Forms Authentication, then you get something in the Global.asax.cs like

FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(formsCookie.Value);
if (ticket.Expired)
{
 Request.Cookies.Remove(FormsAuthentication.FormsCookieName);
 FormsAuthentication.SignOut();
 ...    
     }
else
{ ...
 // renew ticket if old
 ticket = FormsAuthentication.RenewTicketIfOld(ticket);
 ...
     }

And you set the ticket lifetime much longer than the session lifetime. If you're not authenticating, or using a different authentication method, there are similar tricks. Microsoft TFS web interface and SharePoint seem to use these - the give away is that if you click a link on a stale page, you get authentication prompts in the popup window, but if you just use a command, it works.

Henry Troup