为了账号安全,请及时绑定邮箱和手机立即绑定

利用监听器,统计在线人数

标签:
Java

一、 利用HttpSessionListener进行监听

     1. 在session创建的时候,人数+1,在页面显示
     2. 在session销毁的时候,人数-1,在页面显示

二、 扩展一下,在页面显示来访者的详细数据 (如:ip,sessionId,第一次访问时间)

     1. 在浏览器发来请求的时候,利用ServletRequestListener进行监听,获取sessionId,

     2. 并判断sessionId是否存在,不存在就可放入到List中,在页面获取

     3. 在session销毁的时候,顺便将对应的用户从List中移除
@WebListener
public class MyHttpSessionListener implements HttpSessionListener {

    private int userNumber = 0; //在线用户人数

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        userNumber++;
        se.getSession().getServletContext().setAttribute("userNumber", userNumber);
        System.out.println("用户+1");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        userNumber--;
        se.getSession().getServletContext().setAttribute("userNumber", userNumber);
        System.out.println("用户-1");

        //移除用户
        ArrayList<User> userList = null; //在线用户List
        userList = (ArrayList<User>) se.getSession().getServletContext().getAttribute("userList") ;
        if(SessionUtil.getUserBySessionId(userList, se.getSession().getId()) != null){
            userList.remove(SessionUtil.getUserBySessionId(userList, se.getSession().getId()));
        }
    }
}
@WebListener
public class MyServletRequestListener implements ServletRequestListener {

    private ArrayList<User> userList; //在线用户 List

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        userList = (ArrayList<User>) sre.getServletContext().getAttribute("userList");
        if(userList == null){
            userList = new ArrayList<>();
        }

        HttpServletRequest request =  (HttpServletRequest) sre.getServletRequest();
        String sessionIdString = request.getSession().getId();

        //验证sessionId是否存在,不存在就可放入到List中
        if(SessionUtil.getUserBySessionId(userList, sessionIdString) == null){
            User user = new User();
            user.setSessionIdString(sessionIdString);
            user.setIpString(request.getRemoteAddr());
            user.setFirstTimeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            userList.add(user);
        }
        sre.getServletContext().setAttribute("userList", userList);
    }

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {

    }
}
public class SessionUtil {

    public static Object getUserBySessionId(ArrayList<User> userList, String sessionIdString) {

        for(User user : userList){
            if(user.getSessionIdString().equals(sessionIdString)){
                return user;
            }
        }
        return null;
    }
}

效果

发散思维

如何忽略那个不在线但session还未销毁的用户?


分析:问题的根源在于关闭浏览器后某用户的session不会立即销毁。如何忽略那个不在线,但session还未销毁的用户?做到该用户既不计数,也不输出用户信息

解答:当用户请求服务器资源时,记录用户的最后活跃时间。接着拟定一个失效时间,统计在线人数的时候,假设某个用户的最后活跃时间和当前时间的差值大于这个失效时间,也就是说该用户这一段时间都没有和服务器交互了,那么就认为该用户已下线,否则认为他是在线的。没想出百分百完美解决的方法,只能缩小误差的范围

点击查看更多内容
18人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消