一个web应用程序统计在线用户列表的东东

来源:键盘敲击者cncxz  http://olu.desktopit.net/whitepaper.aspx

一般来说,用户离开系统的方式有四种:主动注销、会话超时、直接关闭浏览器、在当前窗口导航到其他页面,对于前两种(正常退出),我们很容易便可将该用户从在线列表中清除;而后两种(非正常退出),由于无法捕获退出事件的精确时间,只能等到会话超时后才能将该用户清除出在线列表。假设我们设置会话超时时间为60分钟,则必须在1小时后才能将非正常退出的用户从在线列表中清除,而在实际应用中,有相当一大批的用户都习惯于非正常退出,所以采用普通方式维护的在线用户列表的时效性可想而知~~

  针对这种情况,2007年十一的时候做了一套解决方案,现在把它整理了一下发布出来,感觉可行的拿去研究一下吧。

  在线用户模块(OnlineUserBlock)的简要介绍
  主要功能特点
  即时有效地提供一份在线用户列表

   本模块是将这种尴尬降至最低的一个尝试。
  在线用户包含会员、访客两种

  实际应用中,站点应该还有许多访客,严格来说他们也算用户的一种(匿名用户),因而本模块的在线用户包含会员(普通用户)、访客(匿名用户)两种。

  控制会员帐号不能在多处同时登陆

  很多web系统(尤其是收费系统)非常厌恶多人共享同一帐号,本模块设置了一个控制开关,开启后会员帐号将禁止在多处同时登陆(要是俩人一个白天一个晚上分时段共享也是没有办法的),先登陆的将被后登陆的挤掉。 

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

  • 核心功能的实现
    • 在线用户列表时效性改进方案
      为在线用户实体增设一个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应用中可以自由调用当前在线用户实体,并且能够按条件(全部用户、全部访客、全部会员)获取全部的在线用户集合。

 

技术文档

下面列出了几个核心类的Class Diagram抓图。
  • oluUserInfo:在线用户信息
  • oluUserInfoProvider:在线用户信息提供者基类(使用本模块必须实现此类)
  • oluMonitor:在线用户监控器
  • oluHttpModule:在线用户模块的自定义Http模块
  • AutoRefreshControl:自动循环刷新控件

 

详细的描述就不写了,可以从 这里下载NDoc 生成的类库文档。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值