继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

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

超级无敌战士之贪财宝宝
关注TA
已关注
手记 1
粉丝 6
获赞 68

一、 利用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还未销毁的用户?做到该用户既不计数,也不输出用户信息

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

打开App,阅读手记
18人推荐
发表评论
随时随地看视频慕课网APP

热门评论

不错  受用了    写的很好  浅显易懂

不错  受用了    写的很好  浅显易懂

查看全部评论