http://www.ibm.com/developerworks/cn/web/wa-lo-comet/html
http://www.ibm.com/developerworks/cn/java/j-lo-comet/html5
在网上查了一下资料,发现轮询和长轮询还有不一样的定义:java
轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后立刻返回响应信息并关闭链接。
优势:后端程序编写比较容易。
缺点:请求中有大半是无用,浪费带宽和服务器资源。
实例:适于小型应用。web
长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住链接,直到有新消息才返回响应信息并关闭链接,客户端处理完响应信息后再向服务器发送新的请求。
优势:在无消息的状况下不会频繁的请求。
缺点:服务器hold链接会消耗资源。
实例:WebQQ、Hi网页版、Facebook IM。ajax
另外,对于长链接和socket链接也有区分:后端
长链接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长链接的请求,服务器端就能源源不断地往客户端输入数据。
优势:消息即时到达,不发无用请求。
缺点:服务器维护一个长链接会增长开销。
实例:Gmail聊天浏览器
Flash Socket:在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript经过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通讯,JavaScript在收到服务器端传送的信息后控制页面的显示。
优势:实现真正的即时通讯,而不是伪即时。
缺点:客户端必须安装Flash插件;非HTTP协议,没法自动穿越防火墙。
实例:网络互动游戏。安全
以上是四种请求方式的介绍和优缺点比较。服务器
长链接工做原理:websocket
从上图能够看出每次数据传送不会关闭链接,链接只会在通讯出现错误时,或是链接重建时关闭(一些防火墙常被设置为丢弃过长的链接, 服务器端能够设置一个超时时间, 超时后通知客户端从新创建链接,并关闭原来的链接)。
长轮询工做原理:
长轮询是如今最为经常使用的方式,和长链接方式的区别就是服务器端在接到请求后挂起,有更新时返回链接即断掉,而后客户端再发起新的链接。
固然如今也有正在弥补以上两种不足的第三种方式WebSocket
不论是长链接仍是长轮询,其实都只是单向通讯,直到WebSocket的出现,才是B/S之间真正的全双工通讯。不过目前WebSocket协议仍在开发中,目前Chrome和Safri浏览器默认支持WebSocket,而FF4和Opera出于安全考虑,默认关闭了WebSocket,IE则不支持(包括9),目前WebSocket协议最新的为“76号草案”。有兴趣能够看如下资料
http://dev.w3.org/html5/websockets/
Comet 实现的方法
最先期的 Web 应用中,主要经过 JavaScript 或者 Meta HTML 标签等手段,定时刷新页面来检测服务端的变化。显然定时刷新页面服务端仍然在被动响应客户端的请求,只不过客户端的请求是连续、频繁的,让用户看起来产生 有服务端自动将信息发过来的错觉。这种方式简单易行,但缺陷也很是明显:可能大部分请求都是无心义的,由于服务端期待的事件没有发生,实际上并无须要发 送的信息,而不得不重复的回应着页面上全部内容给浏览器;另外就是当服务端发生变化时,并不能“实时”的返回,刷新的间隔过短,产生很大的性能浪费,间隔 太长,事件通知又可能晚于用户指望的时间到达。
当绝大部分浏览器提供了 XHR(XmlHttpRequest)对象支持后,Ajax 技术出现并迅速流行,这一阶段作的轮询就没必要每次都返回都返回整个页面中全部的内容,若是服务端没有事件产生,只须要返回极少许内容的 http 报文体。Ajax 能够节省轮询传输中大量的带宽浪费,但它没法减小请求的次数,所以 Ajax 实现的简单轮询仍然有轮询的局限性,对其缺陷只能必定程度缓解,而没法达到质变。
长轮询与简单轮询的最大区别就是链接时间的长短:简单轮询时当页面输出完链接就关闭了,而长轮询通常会保持 30 秒乃至更长时间,当服务器上期待的事件发生,将会马上输出事件通知到客户端,接着关闭链接,同时创建下一个链接开始一次新的长轮询。
长轮询的实现方式优点在于当服务端期待事件发生,数据便当即返回到客户端,期间没有数据返回,再较长的等待时间内也没有新的请求发生,这样可让发送的请求减小不少,而事件通知的灵敏度却大幅提升到几乎是“实时”的程度。
Comet 流是按照长轮询的实现思路进一步发展的产物。令长轮询将事件通知发送回客户端后再也不关闭链接,而是一直保持直到超时事件发生才从新创建新的链接,这种变体 咱们就称为 Comet 流。客户端可使用 XmlHttpRequest 对象中的 readyState 属性来判断是 Receiving 仍是 Loaded。Comet 流理论上可使用一个连接来处理若干次服务端事件通知,更进一步节省了发送到服务端的请求次数。
不管是长轮询仍是 Comet 流,在服务端和客户端都须要维持一个比较长时间的链接状态,这一点在客户端不算什么太大的负担,可是服务端是要同时对多个客户端服务的,按照经典 Request-Response 交互模型,每个请求都占用一个 Web 线程不释放的话,Web 容器的线程则会很快消耗殆尽,而这些线程大部分时间处于空闲等待的状态。这也就是为何 Comet 风格服务很是期待异步处理的缘由,但愿 Web 线程不须要同步的、一对一的处理客户端请求,能作到一个 Web 线程处理多个客户端请求。