MuMu's幽静空间

心平风浪静,志远天地宽……
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

在线用户模块(OnlineUserBlock)解决方案的实现思路

Posted on 2008-06-09 20:30  神旨意  阅读(1318)  评论(0编辑  收藏  举报
  • 核心功能的实现
    • 在线用户列表时效性改进方案
      为在线用户实体增设一个RefreshTime属性,在web系统的标志性页面(也可以是所有页面)上添加一个实现了System.Web.UI.ICallbackEventHandler接口的web控件, 该控件自页面加载成功开始利用javascript脚本无刷新循环调用(周期可配置)一个将当前用户的RefreshTime属性设置为当前时间的服务器端方法, 如果用户离开了所有包含此自动刷新控件的页面,那么RefreshTime属性便不会自动更新了。与此同时,我们在服务器端设置一个计时器,循环判断(周期可配置)在线列表中所有用户的RefreshTime属性, 自动清除那些超过特定时间(可配置,比客户端自动刷新周期长,远小于会话超时时间)不更新RefreshTime属性的用户。 当然,频繁的刷新会增大系统服务器负担,所以我们应该在服务器负担&在线用户列表时效性之间取一个均衡点,设置上文提到的三个参数。
    • 将匿名用户(访客)加入在线名单
      在ASP.NET2.0设置架构中新增加了一个anonymousIdentification元素(具体请参考msdn),设置其enabled 属性值为true可为当前应用程序启用匿名标识,之后调用HttpContext.Current.Request.AnonymousID可获取一个Guid转换而来的字符串, 使用这个字符串作为唯一标识创建普通用户(会员)&匿名用户(访客)的通用实体,在线用户列表即是对这一通用实体集合的维护。
    • 禁止会员同时在多处登录
      这个功能的实现主要用两种途径:①某帐号一旦成功登录后,在退出前不允许再次登录;②登录时判断此前是否有人用当前帐号登录,若有则将其踢出。 对于第一种途径,由于非正常退出现象的存在,将有可能造成用户在某一特定时间内无法正常登录,因而此处采用第二种途径。
  • 在线列表的维护
      下图(图一)描述了如何处理对 ASP.NET 资源的请求。首先,IIS 接收到请求,并将请求调度给 aspnet_isapi.dll;接下来,ASP.NET 引擎对已配置的 HTTP 模块进行初始化;最后将调用正确的 HTTP 处理程序,并呈现被请求的资源,将所生成的标记返回给 IIS 和请求客户端。

      图一:IIS 和 ASP.NET 正在处理请求
      鉴于上述逻辑,在线用户列表维护的核心功能将在一个自定义的Http模块中实现。具体来说,就是在其PostAuthenticateRequest事件中判断当前请求是否由自动刷新控件(上文已交代其存在原因)发出, 若是则不作任何处理;否则,将按当前用户标识(HttpContext.Current.Request.AnonymousID)判断当前在线用户实体是否已创建,并根据判断结果做如下处理(如图二所示):

      图二
      A、若尚未创建在线用户实体
      • 若当前用户未登录(判断HttpContext.Current.User.Identity.IsAuthenticated),则自动创建匿名用户实体并加入在线名单,否则继续下一步;
      • 检测在线用户列表中是否有他人采用当前帐号登录,无则按照当前标识&登录用户标识创建普通用户(会员)并加入在线名单,若有则继续下一步;
      • 判断是否禁止会员同时在多处登录(EnableMemberLoginSingleton),若未禁止则直接创建普通用户并加入在线名单,若已设置禁止则继续下一步;
      • 踢出使用当前帐号登录的其他人,创建普通用户并加入在线名单。
      B、若已创建在线用户实体
      • 若当前在线用户实体为匿名用户(访客)且当前用户未登录(判断HttpContext.Current.User.Identity.IsAuthenticated),或者当前在线用户实体为普通用户(会员)且当前用户已登录,则直接更新当前在线用户的活动时间(ActiveTime)&自动刷新时间(RefreshTime),否则继续下一步;
      • 转换当前在线用户实体(是匿名用户则更改为普通用户,是普通用户则更改为匿名用户)。
      针对这个HttpModule还有以下三点补充:
      • 登录时,创建当前在线用户(会员)实体,并将其加入在线列表(若有必要,须先踢出使用用此帐号登录的其他人)
      • 会员注销时,应将当前用户从在线列表中移除。
      • 创建一个利用脚本无刷新更新当前在线用户自动刷新时间(RefreshTime)的web控件,并将其放置在web系统的主要页面上。
  • 在线用户的调用
    在具体的web应用中可以自由调用当前在线用户实体,并且能够按条件(全部用户、全部访客、全部会员)获取全部的在线用户集合。