WCF后续之旅(9): 通过WCF双向通信实现Session管理[下篇]
一、Session Management Service的实现
现在我们来看看Session Management真正的实现,和我以前的例子不同,我不是把所有的实现都写在WCF service上,而是定义了另一个class来实现所有的业务逻辑:SessionManager。我们分析一下具体的实现逻辑。
1: namespace Artech.SessionManagement.Service
2: {
3: public static class SessionManager
4: {
5: private static object _syncHelper = new object();
6:
7: internal static TimeSpan Timeout
8: { get; set; }
9:
10: public static IDictionary<Guid, SessionInfo> CurrentSessionList
11: { get; set; }
12:
13: public static IDictionary<Guid, ISessionCallback> CurrentCallbackList
14: { get; set; }
15:
16: static SessionManager()
17: {
18: string sessionTimeout = ConfigurationManager.AppSettings["SessionTimeout"];
19: if (string.IsNullOrEmpty(sessionTimeout))
20: {
21: throw new ConfigurationErrorsException("The session timeout application setting is missing");
22: }
23:
24: double timeoutMinute;
25: if (!double.TryParse(sessionTimeout, out timeoutMinute))
26: {
27: throw new ConfigurationErrorsException("The session timeout application setting should be of doubdle type.");
28: }
29:
30: Timeout = new TimeSpan(0, 0, (int)(timeoutMinute * 60));
31: CurrentSessionList = new Dictionary<Guid, SessionInfo>();
32: CurrentCallbackList = new Dictionary<Guid, ISessionCallback>();
33: }
34: //...
35: }
36: }
37:首先来看Field、Property和static constructor的定义。_syncHelper 用于实现多线程同步之用;Timeout是session timeout的时间,可配置;CurrentSessionList和CurrentCallbackList两个dictionary在上面我们已经作过介绍,分别代表当前活动的session列表和callback列表,key均为SessionID。在静态构造函数中,初始化session timeout的时间,和实例化CurrentSessionList和CurrentCallbackList。
接着我们来看看StartSession和EndSession两个方法,这两个方法分别代表Session的开始和结束。
1: public static Guid StartSession(SessionClientInfo clientInfo)
2: {
3: Guid sessionID = Guid.NewGuid();
4: ISessionCallback callback = OperationContext.Current.GetCallbackChannel<ISessionCallback>();
5: SessionInfo sesionInfo = new SessionInfo() { SessionID = sessionID, StartTime = DateTime.Now, LastActivityTime = DateTime.Now, ClientInfo = clientInfo };
6: lock (_syncHelper)
7: {
8: CurrentSessionList.Add(sessionID, sesionInfo);
9: CurrentCallbackList.Add(sessionID, callback);
10: }
11: return sessionID;
12: }
13:
14: public static void EndSession(Guid sessionID)
15: {
16: if (!CurrentSessionList.ContainsKey(sessionID))
17: {
18: return;
19: }
20:
21: lock (_syncHelper)
22: {
23: CurrentCallbackList.Remove(sessionID);
24: CurrentSessionList.Remove(sessionID);
25: }
26: }在StartSession方法中,首先创建一个GUID作为SessionID。通过OperationContext.Current获得callback对象,并根据client端传入的SessionClientInfo 对象创建SessionInfo 对象,最后将callback对象和SessionInfo 对象加入CurrentCallbackList和CurrentSessionList中。由于这两个集合会在多线程的环境下频繁地被访问,所以在对该集合进行添加和删除操作时保持线程同是显得尤为重要,所在在本例中,所有对列表进行添加和删除操作都需要获得_syncHelper加锁下才能执行。与StartSession相对地,EndSession方法仅仅是将SessionID标识的callback对象和SessionInfo 对象从列表中移除。
然后我们来看看如何强行中止掉一个或多个活动的session:KillSessions。
1: public static void KillSessions(IList<Guid> sessionIDs)
2: {
3: lock (_syncHelper)
4: {
5: foreach (Guid sessionID in sessionIDs)
6: {
7: if (!CurrentSessionList.ContainsKey(sessionID))
8: {
9: continue;
10: }
11:
12: SessionInfo sessionInfo =
补充:综合编程 , 其他综合 ,