Welcome

首页 / 软件开发 / WCF / WCF后续之旅(9):通过WCF的双向通信实现Session管理[Part I]

WCF后续之旅(9):通过WCF的双向通信实现Session管理[Part I]2011-01-03 cnblogs artech我们都知道,WCF支持Duplex的消息交换模式,它允许在service的执行过程中实现对client的回调。WCF这种双向通信的方式是我们可以以Event Broker或者订阅/发布的方式来定义和调用WCF Service。今天我们就给大家一个具体的例子:通过WCF的duplex communication方式现在Session管理。

1、Session 管理提供的具体功能

我们的例子实现了下面一些Session Management相关的功能:

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之后,自动退出。

2、Session Timeout的实现原理

在该例子中,最重要的是如何实现timeout的功能,而该功能的核心在于如何探测session的状态(Active、Timeout、Killed)。一般地我们有两种截然不同的方式来实现这样的功能:

I、客户端驱动:这是大多数人会想得到的方式,通过这样的方式实现session status的检测功能:如下图所示,client端调用相应的service开始一个session,并获得SessionID。client端每隔一定的时间调用相应的操作(CheckSessionStatus),并将自己的SessionID传入,进行session status的检测(步骤1),根据返回的状态进行相应的处理;用户的鼠标操作将会调用相应的操作(RenewSession)将session的last active time修正为service端的当前时间(不应该是client的时间)(步骤2)。然而,不可能每次鼠标操作都进行service的调用,这样会频繁的调用service调用肯定会使程序不堪重负。所以会一般会设置一个service调用的时间间隔,也就是在一定的时间端内,只有一次鼠标操作会触发service的调用。由于CheckSessionStatus和RenewSession的调用都是基于某个时间间隔的,所以实时性是怎么也解决不了的。此外,这种形如轮询方式的机制在高并发的情况下也会让service端的压力正大。