springboot 用监听器统计在线人数案例分析
本文在springboot的项目,用HttpSessionListener监听器(监听器的其中一种)统计在线人数,实质是统计session的数量。
思路很简单,但是有个细节没处理好,让我调试了大半天,才把bug搞好。
先写个HttpSessionListener监听器。count 是session的数量(人数),session创建的时候,会触发监听器的sessionCreated方法,session销毁的时候,会触发监听器的sessionDestroyed方法。在监听器中计算完人数count,把他放进servletContext(可以理解为一个仓库,任意请求可以存储和获取里面的属性)。
注意监听器加上@WebListener,这样就不用配置。
@WebListener publicclassOnLineCountimplementsHttpSessionListener{ publicintcount=0;//记录session的数量 //监听session的创建,synchronized防并发bug publicsynchronizedvoidsessionCreated(HttpSessionEventarg0){ System.out.println("【HttpSessionListener监听器】count++增加"); count++; arg0.getSession().getServletContext().setAttribute("count",count); } @Override publicsynchronizedvoidsessionDestroyed(HttpSessionEventarg0){//监听session的撤销 System.out.println("【HttpSessionListener监听器】count--减少"); count--; arg0.getSession().getServletContext().setAttribute("count",count); } }
接着写一个查询session数量的controller,我开始的时候是像下面这样写的,是错误的!
从servletContext中取出count,把count返回前端。
@RequestMapping("/count") @ResponseBody publicStringcount(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse){ Objectcount=httpServletRequest.getServletContext().getAttribute("count"); return"count:"+count; }
这样是错误的,测试你会发现,页面看到count 是null,因为没有创建session,没有触发监听器的统计方法。于是改一下:
@Controller publicclassIndexController{ @RequestMapping("/count") @ResponseBody publicStringcount(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse){ HttpSessionsession=httpServletRequest.getSession(); Objectcount=session.getServletContext().getAttribute("count"); return"count:"+count; } }
HttpSessionsession=httpServletRequest.getSession(); 作用:该用户如果没有sesision则创建session,有则取得session不创建。
改成这样测试,看起来是对的,但是有个问题。一个浏览器对应一个session,你打开2个浏览器,看到count是2,是对的。但是你关了一个浏览器,再打开,应该是2不变才对,但是变成3了,原因是session销毁的方法没有执行,重新打开时,服务器找不到用户原来的session,重新创建了一个session,于是有3个session了,但是浏览器只有2个,也就是模拟应该是只有2个人在线上。
有2个方法可以解决这个问题,一个是在关闭网页的时候,前端去调用一个方法把session销毁。另一个更好的方法是,让服务器记得原来那个session,即把原来的sessionId记录在浏览器,下次打开时,把这个sessionId发送过去,这样服务器就不会重新创建。
代码修改如下:
@Controller publicclassIndexController{ @RequestMapping("/count") @ResponseBody publicStringnumber(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse){ try{//把sessionId记录在浏览器 Cookiec=newCookie("JSESSIONID",URLEncoder.encode(httpServletRequest.getSession().getId(),"utf-8")); c.setPath("/"); //先设置cookie有效期为2天,不用担心,session不会保存2天 c.setMaxAge(48*60*60); httpServletResponse.addCookie(c); }catch(Exceptione){ e.printStackTrace(); } HttpSessionsession=httpServletRequest.getSession(); Objectcount=session.getServletContext().getAttribute("count"); return"count:"+count; } }
总结
以上所述是小编给大家介绍的springboot用监听器统计在线人数案例分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!