有時候你希望你的頁面“一直活着”。也就是說,如果一個使用者填寫一個複雜的表單,在使用者完成之前。你一定不希望session過期。否者使用者可能是以變得非常惱怒。
這也不是簡單的加長session過期時間的事情。如果你這樣做,當通路頁面的使用者離開這個網站,session将會仍舊存活在伺服器的記憶體中很長一段時間。增加session過期時間是一個解決辦法,但是它不是一個很好的解決辦法。
我的目标是:一旦網頁在用戶端被打開,session就一直激活。即使沒有任何回發來重設session的時間。當網頁關閉的時候,session将自然結束。
我這樣來實作這個解決方案:在用戶端每隔一段時間就去"ping"服務端,這個時間少于session的過期時間。這就是Heartbeat設計模式。
麻煩的設定:
為了達到測試的目的。我在web.config中設定session逾時時間為2分鐘。
1 <system.web>
2 <sessionState timeout="2">
3 </sessionState>
4 </system.web>
為了追蹤具體發生了什麼,使用一個公用的函數ODS(在MiscUtilities類中)

1 // ---- ODS (Output Debug String) ----------------------
2 public static void ODS(string Msg)
3 {
4 String Out = String.Format("{0} {1}", DateTime.Now.ToString("hh:mm:ss.ff"), Msg);
5 System.Diagnostics.Debug.WriteLine(Out);
6 }
7

為了觀察session的狀态事件,我在global.asax中添加用于調試的字元串。

1 <%@ Application Language="C#" %>
2 <script RunAt="server">
3
4 void Application_Start(object sender, EventArgs e)
5 {
6 MiscUtilities.ODS("****ApplicationStart");
7 }
8 void Session_Start(object sender, EventArgs e)
9 {
10 MiscUtilities.ODS("Session_Start");
11 }
12 void Session_End(object sender, EventArgs e)
13 {
14 MiscUtilities.ODS("Session_End");
15 }
16

下面是詳細步驟:由于我們需要在服務端有一個方法供用戶端調用。故使用一個WebMethod方法。
1、在頁面上我們必須有一個ScriptManager
2、ScriptManager 的EnablePageMethods 必須設定成true
3、WebMethod 方法必須是public和static的
4、WebMethod 方法必須将EnableSession屬性設定成true
1 <asp:ScriptManager ID="ScriptManager1" runat="server"
2 EnablePageMethods="true">
3 </asp:ScriptManager>

1 public partial class _Default : System.Web.UI.Page
2 {
3 [WebMethod(EnableSession=true ) ]
4 public static void PokePage()
5 {
6 // called by client to refresh session
7 MiscUtilities.ODS("Server: I am poked");
8 }
9

我們需要有一個用戶端的JavaScript定時地去調用服務端的方法。

1 <script type="text/javascript">
2 var HeartBeatTimer;
3 function StartHeartBeat()
4 {
5 // pulse every 10 seconds
6 if (HeartBeatTimer == null)
7 HeartBeatTimer = setInterval("HeartBeat()", 1000 * 10);
8 }
9 function HeartBeat()
10 {
11 // note: ScriptManger must have: EnablePageMethods="true"
12 Sys.Debug.trace("Client: Poke Server");
13 PageMethods.PokePage();
14 }
15 <body id="MyBody" onload="StartHeartBeat();">

沒有"心跳"的,輸入如下:
1 10:22:43.03 ****ApplicationStart
2 10:22:45.13 Session_Start
3 10:25:00.00 Session_End
有"心跳"的,輸出如下:

1 10:26:06.10 ****ApplicationStart
2 10:26:08.05 Session_Start
3 Client: Poke Server
4 10:26:18.93 Server: I am poked
5 Client: Poke Server
6 10:26:28.95 Server: I am poked
7 Client: Poke Server
8 10:26:38.96 Server: I am poked
9 Client: Poke Server
10 10:26:48.98 Server: I am poked
11
12 . . . (lines deleted)
13
14 Client: Poke Server
15 10:29:59.45 Server: I am poked
16 Client: Poke Server
17 10:30:09.47 Server: I am poked
18 Client: Poke Server
19 10:30:19.48 Server: I am poked
20
21 . . . (lines deleted)
22

這樣看起來用戶端閑置的時候,session仍然活着,也就是網站“心跳”着。 (有點扯淡)
本文轉自麒麟部落格園部落格,原文連結:http://www.cnblogs.com/zhuqil/archive/2010/03/26/AH-Ah-ah-ah-Staying-Alive-Staying-Alive.html,如需轉載請自行聯系原作者