如何判斷一個SessionId是否已Timeout?
前言
有同事問,要如何判斷一個SessionId是否已Timeout呢? 直覺想就是在global.asax的Session_Start & Session_End裡面去動手腳,加入一個Hashtable去記錄。但是,如果把Session是放在StateServer或是SQL Server的話,那就不會引發Session_End事件。
研究
在CodeProject中找到了「ASP.NET HttpModule for handling session end with StateServer」一篇文章,它是寫一個HttpModule,再使用Cache的Timeout來模擬Session的Timeout。當Cache Timeout時,再引發自定的SessionEnd事件。
實作
因為自定的SessionEnd事件是Static Event,所以無法使用HttpContext.Current取到Application物件,所以就在SessionEndedEventArgs裡加入HttpApplicationState物件以方便在SessionEnd時,可以存取到Application。
要達到檢查某個SessionId是否Timeout,我們要先用個Hashtable去記錄。
- 在Application_Start事件中建立Hashtable。
{ Debug.WriteLine("Application started"); SessionEndModule.SessionObjectKey = "UserEmail"; SessionEndModule.SessionEnd += new SessionEndEventHandler(SessionTimoutModule_SessionEnd); //建立放SessionID的Hashtable Hashtable htSession = new Hashtable(); Application["SessionList"] = htSession; }
- 在Session_Start事件中把SessionId加到Hashtable之中。
{ Debug.WriteLine("Session started: " + Session.SessionID); Session["UserId"] = new Random().Next(1, 100); Session["UserEmail"] = new Random().Next(100, 1000).ToString() + "@domain.com"; //加入到SessionList ((Hashtable)Application["SessionList"]).Add(Session.SessionID, Session["UserId"]); }
- 在自定的SessionEnd事件中,把SessionId從Hashtable之中移除。
{ Debug.WriteLine("SessionTimoutModule_SessionEnd : SessionId : " + e.SessionId); // This will be the value in the session for the key specified in Application_Start object sessionObject = e.SessionObject; string val = (sessionObject == null) ? "[null]" : sessionObject.ToString(); Debug.WriteLine("Returned value: " + val); //移除SessionList ((Hashtable)e.HttpApp["SessionList"]).Remove(e.SessionId); }
- 要檢查SessionId是否有Timeout,只要Check Hashtable之中是否有該SessionId即可!
{ string sid = txtSessionID.Text.Trim(); if (((Hashtable)Application["SessionList"]).ContainsKey(sid)) lblMsg.Text = "SessionID:" + sid + " Session還沒TimeOut!"; else lblMsg.Text = "SessionID:" + sid + " Session已經TimeOut!"; }
- Web.config中sessionState設定為StateServer,timeout設定為1分鐘。另外,記得ASP.NET State Service啟動哦!
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="1" cookieless="false"/>
附上測試程式碼:
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^