HTTP本质是由客户端发起请求获取数据,要实现服务端推送消息,最简单的方式是利用ajax不断的轮询,间隔设置越小实时性越高,同时对服务器的压力越大。如果服务端产生消息的间隔比轮询间隔大很多的话,很多请求都是落空的,感觉有点浪费。自然想到使用长轮询的方式改进,请求到达服务端,当有消息的时候立即返回,并再发起一个请求,如果没有消息,则保持连接一段时间,比如30秒,然后重新发起请求。 这样请求的间隔根据消息产生的频率有个最大30秒弹性的间隔,并且能保证消息的实时推送。从fiddler抓包来看,每个客户端一直有个http连接和服务端处于连接状态,(ps:在网上看长连接和长轮询,iframe方式ajax方式,一直搞不清区别,我都认为一致了)。
要实现账号重复登录踢出原先登录的账号,则需要定向推送消息,如何找到原先登录的客户端?需要找一个客户端连接唯一的标识,比如sessionid,每个客户端登录后,注册到已登录map中,并且对应生成一个消息队列。 后来登录的账户只要在已登录map中找到sessionid,然后往sessionid对应的消息队列推送消息,每个客户端保持的长连接实时从自己对应的消息队列中poll消息,然后执行相应的操作就行了。
流程图:
代码:
public class LoginServlet extends HttpServlet{
@Override
public void init() throws ServletException {
// TODO Auto-generated method stub
ServletContext context = this.g