服务器推送的实现—基于EventSource

1、服务器推送理解

  首先要知道为何使用服务器推送,回答这个问题其实就是至关于回答,服务器推送的优势,能够从两个方面来思考:json

1.1 服务器推送的目的

  及时的将客户端感兴趣的数据推送给它。浏览器

1.2 不是用服务器推送怎么来实现需求

  不使用服务端推送,那就只能由客户端按期对服务器发送请求,来获取是否有须要的数据。这样作有几个缺点:服务器

  • 不能及时的获取,最大延时时间为轮询间隔。
  • 浪费资源,大部分的请求,都不会获得数据
  • 轮询间隔短会对服务器形成较大的压力。

1.3 使用服务器推送能够带来什么好处

  我理解的有两个好处,一是及时,还有就是消耗资源稳定(消耗一个链接数)。及时很好理解,就是服务器知道数据何时发生变化,发生变化的时候就进行推送。而消耗资源稳定,则是由于只有一个链接,全部的数据都从这么链接发送。app

1.4 使用服务器推送有哪些局限性

  固然就是每个客户端都须要维护一个长链接,客户端数量增多的时候,会对服务器形成较大的压力。函数

1.5使用服务器推送的场景

  若是知足如下条件,那么使用它是最好的作法,若不所有知足,则酌情考虑:学习

  • 要求客户端能及时的感知服务器数据的变化
  • 客户端的数量能在服务器的承受范围内

2、服务器推送的实现

  服务器推送的实现有不少种方式,这一篇博客使用EventSource来实现功能。若要实现服务器推送,须要客户端和服务端同时对其进行支持。spa

2.1 客户端代码

  客户端代码比较简单,实现一个回调函数便可:code

new EventSource("longConnection").onmessage = function(event) {
    $scope.$apply(function() {    
        alert(event.data);        
    }); 
};

  回调函数中的event.data就是服务器发送的数据,此时能够对它进行其它操做。对象

2.2 服务端代码

  服务端的代码通常放到一个循环中:blog

response.setContentType("text/event-stream;charset=UTF-8");
response.setHeader("Cache-Control","no-cache");
response.setHeader("Connection","keep-alive");
PrintWriter out=response.getWriter();
while(true){
    out.print("data: " + 传递的数据 + "\n\n");
    out.flush();
}

  只要不把链接关闭,那么每一次刷新,都会讲数据发送到客户端,并触发onmessage方法。

2.3 注意事项

2.3.1 浏览器的支持问题

  默认IE是不支持EventSource对象的,解决办法是引入一个js文件eventsource.min.js,可是也只能支持IE8及以上。

2.3.2 服务器数据问题

  从上面的例子中能够发现,往客户端发送数据的代码是写在一个死循环中,那么怎么才能实现当敏感数据发生变化时,才使其执行呢,可行性办法有不少,如今提供一个方法,在全局范围内使用LinkedBlockingQueue对象,当有须要发送的数据时,将数据放到队列中,而后在循环中调用poll方法便可。

3、EventSource深刻理解

  若是细心的话能够发现,在服务端代码中,写数据的使用使用了以下格式:

out.print("data: " + 传递的数据 + "\n\n");
out.flush();

  每次写完刷新可不用说,重点是写数据的时候,有一个前缀和后缀,那么这个是有什么规定吗,仍是说与页面js代码一一对应便可,答案是有规定的。下面使用F12对长链接进行观察,能够看到以下内容:

  具体可使用哪些前缀,有id,data,event,retry和空白,然后缀使用两个换行,实际上这表明着是一个空行,学习过servlet上传的可能会理解。

  • id:表明本次事件
  • data:表示传递的数据
  • event:表明触发的事件
  • retry:表明断开重连后再次等待的时间

  通常用法都是在传递的数据中使用json,里面存放须要调用的方法名,调用参数放在后面,这样就能够根据不一样的数据类型进行不一样的处理。

  一样的客户端代码中使用了onmessage方法,那么是否只有这一个方法呢,其实还有额外的两个方法,这两个方法视状况使用 :

  • onopen:这个是在链接成功后触发的。
  • onerror:这个是在出现异常的时候出发的。

4、总结

  这个只是服务端推送的一种实现方式,基本能知足要求,还有其余方式,后面会介绍。

相关文章
相关标签/搜索