WCF後續之旅(9):通過WCF的雙向通信實現Session管理[上篇]
一、Session 管理提供的具體功能
- Start/End Session:可以調用service開始一個新的Session或者結束掉一個現有的Session。當開始一個Session的時候,service根據client端傳入的client相關的信息(ClientInfo),創建一個SessionInfo對象,該對象由一個GUID類型的SessionID唯一標識,代表一個具體的Client和Service的Session。在service端,通過一個dictionary維護者一個當前所有的active session列表,key為SessionID,value是SessionInfo對象。當client調用相應的service,傳入對應的SessionID,該SessionID對應的SessionInfo從該session列表中移除。
- Session Timeout:如同ASP.NET具有一個Timeout的時間一樣,我們的例子也具有timeout的機製。在client可以注冊timeout事件,某個session timeout,service會通過在start session中指定的callback回調相應的操作(OnTimeout)並處罰client注冊的timeout事件。session timeout後,SessionInfo對象從active session列表中移除。 比如在本例中,我們通過注冊事件使得timeout後,程序在顯示timeout message之後,自動退出。
- Session Renew:session timeout判斷的依據是client最後活動的時間(last activity time),而該事件反映的是最後一次鼠標操作的時間(假設我們的client是一個GUI應用)。所以從session的生命管理來講,用戶的每次鼠標操作實際上將session的時間延長到session timeout的時間。
- Session Listing Viewing:Administrator或者某個具有相應權限的用戶,可以查看當前活動的session列表和session相關的信息,比如IP地址、主機名稱、用戶名、session開始的時間和最後一次活動的時間,見下圖。
- Session Killing:如何發現某個用戶正在做一些不該做的事情,或者發現當前的並發量太大,管理員可以強行殺掉某個正在活動的Session。同session timeout一樣,client端可以注冊session killed事件。當session被強行中止後,service回調client相應的方法(OnSessionKilled),觸發該事件。比如在本例中,我們通過注冊事件使得某個client對應的session被殺掉後,該client程序在顯示message之後,自動退出。
二、Session Timeout的實現原理
1、客戶端驅動
2、服務端驅動
System.Runtime.Remoting.Lifetime.ISponsor)引用lease對象. 當Lease Manager檢測到某個remote object的lease超時,Remoting不會馬上對其進行垃圾回收,而是找到該lease的Sponsor對象,通過Sponsor對象回調Renewal方法(Sponsor處於client端),返回一個Timespan對象,表明需要將remote object的lifetime延長的時間,如何該值小於或者等於零,則不需要延長,該對象將會被回收掉;否則將lifetime延長至相應的時間。同時,client的每次遠程調用,都會自動實現對lifetime的Renew功能。(詳細內容可以參考我的文章:[原創]我所理解的Remoting (2) :遠程對象的生命周期管理-Part II)
步驟一
步驟二
步驟三
步驟四
步驟五
注:可能有人會說,為什麼不將LastActivityTime返回到service端,service將session的LastActivityTime設定成該值就可以了呀?實際上,這樣做依賴於這樣的一個假設:client端的時間和server端的時間是一致的。很顯然,我們不能作出這樣的假設。
三、整個應用的結構
1: namespace Artech.SessionManagement.Contract
2: {
3: [DataContract]
4: public class SessionClientInfo
5: {
6: [DataMember]
7: public string IPAddress{ get; set; }
8:
9: [DataMember]
10: public string HostName{ get; set; }
11:
12: [DataMember]
13: public string UserName{ get; set; }
14:
15: [DataMember]
16: public IDictionary<string, string> ExtendedProperties{ get; set; }
17: }
18: }
1: namespace Artech.SessionManagement.Contract
2: {
3: [DataContract]
4: [KnownType(typeof(SessionClientInfo))]
5: public class SessionInfo
6: {
7: [DataMember]
8: public Guid SessionID{ get; set; }
9: [DataMember]
10: public DateTime StartTime{ get; set; }
11: [DataMember]
12: public DateTime LastActivityTime{get;set;}
13: [DataMember]
14: public SessionClientInfo ClientInfo{ get; set; }
15: public bool IsTimeout{ get; set; }
16: }
17: }
18:
1: namespace Artech.SessionManagement.Contract
2: {
3: public interface ISessionCallback
4: {
5: [OperationContract]
6: TimeSpan Renew();
7:
8: [OperationContract(IsOneWay = true)]
9: void OnSessionKilled(SessionInfo sessionInfo);
10:
11: [OperationContract(IsOneWay = true)]
12: void OnSessionTimeout(SessionInfo sessionInfo);
13: }
14: }
1: namespace Artech.SessionManagement.Contract
2: {
3: [ServiceContract(CallbackContract = typeof(ISessionCallback))]
4: public interface ISessionManagement
5: {
6: [OperationContract]
7: Guid StartSession(SessionClientInfo clientInfo, out TimeSpan timeout);
8:
9: [OperationContract]
10: void EndSession(Guid sessionID);
11:
12: [OperationContract]
13: IList<SessionInfo> GetActiveSessions();
14:
15: [OperationContract]
16: void KillSessions(IList<Guid> sessionIDs);
17: }
18: }
具體實現請參閱Part II.
WCF後續之旅:
WCF後續之旅(1): WCF是如何通過Binding進行通信的WCF後續之旅(2): 如何對Channel Layer進行擴展——創建自定義Channel
WCF後續之旅(3): WCF Service Mode Layer 的中樞—Dispatcher
WCF後續之旅(4):WCF Extension Point 概覽
WCF後續之旅(5): 通過WCF Extension實現Localization
WCF後續之旅(6): 通過WCF Extension實現Context信息的傳遞
WCF後續之旅(7):通過WCF Extension實現和Enterprise Library Unity Container的集成
WCF後續之旅(8):通過WCF Extension 實現與MS Enterprise Library Policy Injection Application Block 的集成
WCF後續之旅(9):通過WCF的雙向通信實現Session管理[Part I]
WCF後續之旅(9): 通過WCF雙向通信實現Session管理[Part II]
WCF後續之旅(10): 通過WCF Extension實現以對象池的方式創建Service Instance
WCF後續之旅(11): 關於並發、回調的線程關聯性(Thread Affinity)
WCF後續之旅(12): 線程關聯性(Thread Affinity)對WCF並發訪問的影響
WCF後續之旅(13): 創建一個簡單的WCF SOAP Message攔截、轉發工具[上篇]
WCF後續之旅(13):創建一個簡單的SOAP Message攔截、轉發工具[下篇]
WCF後續之旅(14):TCP端口共享
WCF後續之旅(15): 邏輯地址和物理地址
WCF後續之旅(16): 消息是如何分發到Endpoint的--消息篩選(Message Filter)
WCF後續之旅(17):通過tcpTracer進行消息的路由
作者:蔣金楠
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
最後更新:2017-10-30 17:04:42