前言
首先怎么才算登录人数,一般规定用户登录后才算,但是登陆后会出现几种情况,用户主动退出登录,长时间不点击和主动关闭浏览器都会导致会话失效,另外并发登录人数限制和管理员在线踢出用户都会影响登录人数
而一般的做法就是写个servlet会话监听器去监听登录,当有会话建立时并且已经成功登录和先判断该用户是否已经正在线,统计相关信息,然后就是退出浏览器只能等会话失效才算离线。用这种方法去做,简单.但是实时效果不是太好但是发现我得session是用shiro管理的,大部分应用离不开shiro,而且shiro的sessionId每次是不一样的,也就是说,同一用户登录,在缓存中通过用户名产生的会话id不一样,造成同一用户登录重新登录会变成不同用户而在线人数不对。
而另一种更好并且统计更准确的是利用redis缓存信息(遇到了瓶颈,也是这个sessionId每次不一样,但是如果把shiro换掉或者做成分布式可以解决),大概是这样的想法,现在redis中放两组key,根据需求一组存放登陆用户的SessionId与ClientUser的Json数据,另一组存放存放登录用户的UID与SessionId对于的数据,然后利用该监听器,,只要一有会话差生,就从redis登记表(封装各类实时统计的方法)中查看,以一定规则查看是否登录,这里可以判断是游客还是会员,然后记录相关登记信息等等,放在session中,这种统计方法更实时,统计内容更多,但是因为shiro的问题,最终统计很不准确,因为这个sessionId还必须是准确才行
会话列表
要能准确的实时统计,得先解决上面涉及的5个影响因素
- 并发登录人数控制 核心思想就是利用监听器根据那个用户名得到sessionId然后踢掉,缓存同步(见并发登陆人数控制)
- 用户主动退出和会话正常死亡通过监听器解决
3.关闭浏览器通过缩短会话存活时间保证(不一定合理,因为该项目纯粹娱乐所以可以这样做) - 强制用户退出 根据sessionId让session失效,logout就行了
不过这里比较棘手的就是的就是那个强制退出的会话怎么清除,如果不清除,缓存中会得到空指针,最头疼的是服务器崩溃,利用缓存中的方法可以得到所有活跃的会话,包括失效的。通过异常删选出失效的会话并删除,最后就剩下正常的会话列表了
当然这时传统的做法,不能完全模拟实时统计,最有效的方法就是用心跳方式解决
码上有戏
|
|