服务端主动推送数据到客户端

一般状况下,打开网页或app去查询或者刷新时,客户端向服务器发出请求而后返回数据,客户端与服务端对应的模式是: 客户端请求--服务端响应, 而在有些状况下,服务端会主动推送一些信息到客户端,例如:新闻的订阅,天气的提醒等等,那么在这样的模式下,会有些问题值得思考:html

1)应用服务器如何肯定每个应用所在的设备?前端

2)服务端把消息推到哪,客户端又不像服务器有一个固定的地址?web

3)服务端主动推送到客户端是怎么一个过程?chrome

假设一个场景,商家在商家后台须要实时的获取到有没有新订单,有的话是几个;这个需求相似与平常中使用QQ或者微信时的新信息提醒同样,只要有新信息就须要提醒;商家基本在PC上使用,各式浏览器都有:如 IE系列(7.0,8.0,9.0及以上),chrome内核,firefox等;功能所属的部署在Tomcat 6.0上,若是技术须要能够部署到 Tomcat 7.0上。跨域

这种浏览器与服务器实时通讯的方式有哪些方式。浏览器

一、AJAX轮询

这是咱们最天然想到的。 采用常规AJAX轮询的方式,每10s或者30s轮询一次,既能够判断出有有多少个新订单进入,且这种时间间隔对于消息提醒也是能够接受的。这种技术方式实现起来很是简单,目前的机器都是能够机器的,前端浏览器也都支持。服务器

可是这种方式会有很是严重的问题,就是须要不断的向服务器发送消息询问,若是有1w个商家打开了浏览器,采用10s轮询的方式,则服务器则会承担1000 的QPS,这1w个商家可能只有10个有订单通知;这种方式会对服务器形成极大的性能浪费。微信

还有一个相似的轮询是使用JSONP跨域请求的方式轮询,在实现起来有差异,但基本原理都是相同的,都是客户端不断的向服务器发起请求。websocket

优势:实现简单。网络

缺点:这是经过模拟服务器发起的通讯,不是实时通讯,不顾及应用的状态改变而盲目检查更新,致使服务器资源的浪费,且会加剧网络负载,拖累服务器。

二、comet

Comet是一种用于Web的推送技术,能使服务器实时地将更新的信息传送到客户端,而无须客户端发出请求,目前主要实现方法是长轮询,长轮询 (long polling) 是在打开一条链接之后保持,等待服务器推送来数据再关闭,能够采用HTTP长轮询和XHR长轮询两种方式。

  • HTTP 和JSONP方式的长轮询

把 script 标签附加到页面上以让脚本执行。服务器会挂起链接直到有事件发生,接着把脚本内容发送回浏览器,而后从新打开另外一个 script 标签来获取下一个事件,从而实现长轮询的模型。

  • XHR长轮询

这种方式是使用比较多的长轮询模式。客户端打开一个到服务器端的 AJAX 请求而后等待响应;服务器端须要一些特定的功能来容许请求被挂起,只要一有事件发生,服务器端就会在挂起的请求中送回响应并关闭该请求。客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,从新创建链接;如此循环。

如今浏览器已经支持CROS的跨域方式请求,所以HTTP和JSONP的长轮询方式是慢慢被淘汰的一种技术,建议采用XHR长轮询。

优势:客户端很容易实现良好的错误处理系统和超时管理,实现成本与Ajax轮询的方式相似。

缺点:须要服务器端有特殊的功能来临时挂起链接。当客户端发起的链接较多时,服务器端会长期保持多个链接,具备必定的风险。

Comet实现要点:

  • 不要在同一客户端同时使用超过两个的 HTTP 长链接

HTTP 1.1 规范中规定,客户端不该该与服务器端创建超过两个的 HTTP 链接, 新的链接会被阻塞,在IE浏览器中严格遵照了这种规定。

  • 服务器端的性能和可扩展性 

通常 Web 服务器会为每一个链接建立一个线程,若是在大型的商业应用中使用 Comet,服务器端须要维护大量并发的长链接。在这种应用背景下,服务器端须要考虑负载均衡和集群技术;或是在服务器端为长链接做一些改进。

  • 在客户和服务器之间保持“心跳”信息

在浏览器与服务器之间维持一个长链接会为通讯带来一些不肯定性:由于数据传输是随机的,客户端不知道什么时候服务器才有数据传送。服务器端须要确保当客户端再也不工做时,释放为这个客户端分配的资源,防止内存泄漏。所以须要一种机制使双方知道双方都在正常运行。

服务器端在阻塞读时会设置一个时限,超时后阻塞读调用会返回,同时发给客户端没有新数据到达的心跳信息。此时若是客户端已经关闭,服务器往通道写数据会出现异常,服务器端就会及时释放为这个客户端分配的资源。

若是客户端使用的是基于 AJAX 的长轮询方式;服务器端返回数据、关闭链接后,通过某个时限没有收到客户端的再次请求,会认为客户端不能正常工做,会释放为这个客户端分配、维护的资源。

  • 当服务器处理信息出现异常状况,须要发送错误信息通知客户端,同时释放资源、关闭链接。

三、iframe

iframe 是很早就存在的一种 HTML 标记, 经过在 HTML 页面里嵌入一个隐蔵帧,而后将这个隐蔵帧的 SRC 属性设为对一个长链接的请求,服务器端就能源源不断地往客户端输入数据。

优势:

这种方式每次数据传送不会关闭链接,链接只会在通讯出现错误时,或是链接重建时关闭(一些防火墙常被设置为丢弃过长的链接, 服务器端能够设置一个超时时间, 超时后通知客户端从新创建链接,并关闭原来的链接)。

缺点:

IE、Morzilla Firefox 下端的进度栏都会显示加载没有完成,并且 IE 上方的图标会不停的转动,表示加载正在进行。

Google 的天才们使用一个称为“htmlfile”的 ActiveX 解决了在 IE 中的加载显示问题,并将这种方法用到了 gmail+gtalk 产品中。Alex Russell 在 “What else is burried down in the depth’s of Google’s amazing JavaScript?”文章中介绍了这种方法。Zeitoun 网站提供的 comet-iframe.tar.gz,封装了一个基于 iframe 和 htmlfile 的 JavaScript comet 对象,支持 IE、Mozilla Firefox 浏览器,能够做为参考。

四、websocket

WebSocket是HTML5开始提供的一种在单个 TCP 链接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,WebSocketAPI被W3C定为标准。在WebSocket API中,浏览器和服务器只须要作一个握手的动做,而后,浏览器和服务器之间就造成了一条快速通道。二者之间就直接能够数据互相传送。

  • 浏览器支持
浏览器 版本支持
Chrome 4+
Firefox 4+
IE 10+
Opera 10+
Safari 5+

五、总结

  • HTML5 websoket
  • WebSocket经过Flash
  • AJAX长轮询
  • XHR长时间链接(XHR长轮询)
  • XHR Multipart Streaming(XHR多流媒体流)
  • 不可见的Iframe
  • <script>标签的长时间链接(可跨域)(HTTP和JSONP方式的长轮询)

总结下来长轮询不是一个很好的方案,并且对于服务器而言是有风险的;另外支持WebSocket协议的浏览器都比较新,特比是IE须要10以上的版本;而咱们的业务是面向于商家端,商家的浏览器版本相对较低,不少对WebSocket都不支持;相对而言Comet的方式比较适合,也有相应的实现框架,实现成本最低。

相关文章
相关标签/搜索