Wednesday, June 17, 2009

Sometimes you want your web page to 'stay alive'. That is, if a user is filling out a complicated form, you do not want the session to time out before they are finished.

It's not simply a matter of increasing the session timeout to a very large value. If you do that, the sessions would be left active in the server memory for hours—long after the visitors have left the site. Increasing the session timeout IS a solution… but not necessarily a good solution.

The goal is that the session should stay active as long as the web page is open on the client machine …even if there are no post backs to reset the session timer. When the web page is closed, the session should time out normally.

I implemented a solution for this: The client will "ping" the server at intervals of less than the session timeout which will reset the session timer. This is known as the Heartbeat design pattern.

For testing purposes, I set the Session Timeout to two minutes in web.config:

<system.web>

<sessionStatetimeout="2">

sessionState>

To trace what is happening, I used a utility function called ODS (it's in a class called MiscUtilities):

/// ---- ODS ---------------------------------------

///

/// Output Debug String with time stamp.

///

publicstaticvoid ODS(string Msg)

{

String Out = String.Format("{0} {1}",

DateTime.Now.ToString("hh:mm:ss.ff"), Msg);

System.Diagnostics.Debug.WriteLine(Out);

}

To watch the Session State events, I added debugging strings to the global.asax file:

@ApplicationLanguage="C#"%>

<scriptRunAt="server">

void Application_Start(object sender, EventArgs e)

{

MiscUtilities.ODS("****ApplicationStart");

}

void Session_Start(object sender, EventArgs e)

{

MiscUtilities.ODS("Session_Start");

}

void Session_End(object sender, EventArgs e)

{

MiscUtilities.ODS("Session_End");

}

Here are the details:

We need a method at the server for the client to call. We use a WebMethod.

1. There must be a ScriptManager on the page.
2. The ScriptManager must have EnablePageMethods set to true.
3. The WebMethod must be public and static.
4. The WebMethod must have the EnableSession attribute set to true.

<asp:ScriptManagerID="ScriptManager1"runat="server"

EnablePageMethods="true">

asp:ScriptManager>

publicpartialclass_Default : System.Web.UI.Page

{

[WebMethod(EnableSession=true ) ]

publicstaticvoid PokePage()

{

// called by client to refresh session

MiscUtilities.ODS("Server: I am poked");

}

We need JavaScript at the client to call the server function at fixed intervals:

6 comments:

i have a umberella asp.net website with tabs (links to 4 other asp.net sites). i want to have the sessions for all of them alive even if the user is working on one of the sites. How can i do this (if possible). Thanks in advance.

i have a umberella asp.net website with tabs (links to 4 other asp.net sites). I am opening the page of the clicked tab in a iframe i want to have the sessions for all of them alive even if the user is working on one of the sites. How can i do this (if possible). Thanks in advance.

If they are different applications, you may be able tom implement this using a third-party state server, or maybe even using the built-in option of storing the session in an SQL database (but I'm not sure of the second option).