使用 servlet web监听器统计在线用户信息及人数

需要解决的问题:

  1. session实现登录
    1. 用户登录成功,将用户信息保存在session中
    2. 创建一个过滤器:查看session中是否有用户信息,没有则需要重新登录
  2. 怎么通过session查看在线人数、所有在线用户列表,查看游客列表,登录者列表
    通过session监听器可以监听session的生命周期,通过request监听器可以获取在ip地址使用 servlet web监听器统计在线用户信息及人数_第1张图片
    1. 不正常登出:关闭浏览器不能及时删除session
      解决:用户在线的实现模式是:在网页后台执行一个任务,每隔一段时间(比如1分钟)就向服务端发送心跳,以证明该用户在线,如果在一段时间内未收到该用户的心跳(比如2分钟),那么就将该用户移出在线队列。
    2. 同一浏览器关闭后重新打开人数也会+1(但是同一浏览器不关闭使用新的网页访问的话人数倒是不会+1)
      解决:可以根据ip相同解决
    3. 不同浏览器打开网页后人数也会+1,也就是同一台电脑多多个浏览器登录页面这其实算是一个用户,但是这里会统计出多个用户。
      解决:根据ip解决
    4. 用户正常登出时,session失效.session.invalidate()方法。该方法可以清除session对象中的所有信息。
    5. 踢出用户:
      1. 方法1:每一个用户登录后,都将session保存在一个容器中,比如hashmap,后台可以根据容器获取到用户的信息进行展示,踢出用户,即将用户session设置为失效,用户权限拦截发现用户所要访问的页面需要登录权限,则将其跳转到登录页
      2. 方法2:使用shiro,踢出用户,就是使用shiro的sessionManager将特定用户session删除,那么发现用户没有认证,就需要登录
  3. 怎么实现同一用户只能在同一时间只能在一个地方登录:(并不是所有公司都有这个需求,一般游戏,聊天等软件才会有这个要求)
    思路:根据同一用户的用户名相同进行处理
    1. 方案一:仅仅使用servlet实现
      (1)创建一个共享容器,比如hashmap,如果要考虑线程安全,可以使用concurrentMap
      (2)用户A使用账号登录,如果验证通过,就Session.setAttribute(用户名,用户),将用户名作为key,Session作为value,保存在map中。
      (3)用户B使用同账号登录,也会验证通过了,那么map通过用户名获取到用户A的Session,取名为sessionA,再使用sessionA.removeAttribute("用户名");
      (4)用户B再将Session.setAttribute(用户名,用户),将用户名作为key,Session作为value,保存在map中,会覆盖掉第二步的key-value,或者在第三步删除该key-value.
      好像有问题,因为原来的session没有改变,变的只是容器内的session

    2. 方案二:使用shiro实现,在用户认证时
      (1)用户A第一次登录的时候,如果验证通过,将用户名作为key,jsessionid作为value,保存在redis中,再将用户A保存在session中
      (2)用户B使用同一个账号进行登录,如果账号验证通过,就使用redis通过用户名获取到jsessionid
      (3)然后再使用shiro中的sessionManager通过jsessionid获取到session,然后再删除session,就踢出了用户A
      (4)用户B再将用户名作为key,jsessionid作为value,保存在redis中,再将用户B保存在session中

  4. 单点登录:所有有应用系统共享一个身份认证系统

你可能感兴趣的:(Servlet)