基于comet的实时web应用:长轮询和服务器端推送
2016-04-05 10:27
531 查看
前半部分转载自 http://www.ibm.com/developerworks/cn/web/wa-lo-comet/
基于 AJAX 的长轮询(long-polling)方式
AJAX 的出现使得 JavaScript 可以调用 XMLHttpRequest 对象发出 HTTP 请求,JavaScript 响应处理函数根据服务器返回的信息对 HTML 页面的显示进行更新。使用 AJAX 实现“服务器推”与传统的 AJAX 应用不同之处在于:
服务器端会阻塞请求直到有数据传递或超时才返回。
客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。
图
2. 基于长轮询的服务器推模型
![](http://www.ibm.com/developerworks/cn/web/wa-lo-comet/fig002.jpg)
一些应用及示例如 “Meebo”, “Pushlet Chat” 都采用了这种长轮询的方式。相对于“轮询”(poll),这种长轮询方式也可以称为“拉”(pull)。因为这种方案基于 AJAX,具有以下一些优点:请求异步发出;无须安装插件;IE、Mozilla FireFox 都支持 AJAX。
在这种长轮询方式下,客户端是在 XMLHttpRequest 的 readystate 为 4(即数据传输结束)时调用回调函数,进行信息处理。当 readystate 为 4 时,数据传输结束,连接已经关闭。Mozilla Firefox 提供了对 Streaming AJAX 的支持, 即 readystate 为 3 时(数据仍在传输中),客户端可以读取数据,从而无须关闭连接,就能读取处理服务器端返回的信息。IE 在 readystate 为 3 时,不能读取服务器返回的数据,目前 IE 不支持基于 Streaming
AJAX。
基于 Iframe 及 htmlfile 的流(streaming)方式
iframe 是很早就存在的一种 HTML 标记, 通过在 HTML 页面里嵌入一个隐蔵帧,然后将这个隐蔵帧的 SRC 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。
图
3. 基于流方式的服务器推模型
![](http://www.ibm.com/developerworks/cn/web/wa-lo-comet/fig003.jpg)
上节提到的 AJAX 方案是在 JavaScript 里处理 XMLHttpRequest 从服务器取回的数据,然后 Javascript 可以很方便的去控制 HTML 页面的显示。同样的思路用在 iframe 方案的客户端,iframe 服务器端并不返回直接显示在页面的数据,而是返回对客户端 Javascript 函数的调用,如“
从 图 3 可以看到,每次数据传送不会关闭连接,连接只会在通信出现错误时,或是连接重建时关闭(一些防火墙常被设置为丢弃过长的连接, 服务器端可以设置一个超时时间, 超时后通知客户端重新建立连接,并关闭原来的连接)。
对于iframe长连接,服务器会维护这个长连接,比如说服务器端脚本会使用true循环维持连接,在有数据更新的时候传输代码回客户端执行,形式就如同“
使用流解决方案时,浏览器会改善一个完整的HTTP请求,但服务器会发送并保持一个处于打开状态的响应,该响应持续更新并无限期处于打开状态。每当有消息可发送时该响应就会被更新,但服务器永远不会发出响应完成的信号,这样连接会一起保持在打开状态以便后续消息的发送。但是,由于流仍封装在HTTP中,其间防火墙和代理服务器可能会对响应消息进行缓冲,造成消息传递的时延。因此当检测到缓冲代理服务器时,许多流解决方案就回退到长轮询方式。
综上所述,所有这些提供实时数据的方式都会涉及HTTP请求和响应报头,其中包含有大量额外的、不必要的报头数据,会造成传输延迟。最重要的是,全双工连接需要的不仅仅是服务器到客户端的下行连接。为了在半双工HTTP的基础上模拟全双工通信,目前许多解决方案都使用两个连接:一个用于下行数据流,另一个用于上行数据流。这两个连接的保持和协作也会造成大量的资源消耗,并增加了复杂度。
基于 AJAX 的长轮询(long-polling)方式
AJAX 的出现使得 JavaScript 可以调用 XMLHttpRequest 对象发出 HTTP 请求,JavaScript 响应处理函数根据服务器返回的信息对 HTML 页面的显示进行更新。使用 AJAX 实现“服务器推”与传统的 AJAX 应用不同之处在于:
服务器端会阻塞请求直到有数据传递或超时才返回。
客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。
图
2. 基于长轮询的服务器推模型
![](http://www.ibm.com/developerworks/cn/web/wa-lo-comet/fig002.jpg)
一些应用及示例如 “Meebo”, “Pushlet Chat” 都采用了这种长轮询的方式。相对于“轮询”(poll),这种长轮询方式也可以称为“拉”(pull)。因为这种方案基于 AJAX,具有以下一些优点:请求异步发出;无须安装插件;IE、Mozilla FireFox 都支持 AJAX。
在这种长轮询方式下,客户端是在 XMLHttpRequest 的 readystate 为 4(即数据传输结束)时调用回调函数,进行信息处理。当 readystate 为 4 时,数据传输结束,连接已经关闭。Mozilla Firefox 提供了对 Streaming AJAX 的支持, 即 readystate 为 3 时(数据仍在传输中),客户端可以读取数据,从而无须关闭连接,就能读取处理服务器端返回的信息。IE 在 readystate 为 3 时,不能读取服务器返回的数据,目前 IE 不支持基于 Streaming
AJAX。
基于 Iframe 及 htmlfile 的流(streaming)方式
iframe 是很早就存在的一种 HTML 标记, 通过在 HTML 页面里嵌入一个隐蔵帧,然后将这个隐蔵帧的 SRC 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。
图
3. 基于流方式的服务器推模型
![](http://www.ibm.com/developerworks/cn/web/wa-lo-comet/fig003.jpg)
上节提到的 AJAX 方案是在 JavaScript 里处理 XMLHttpRequest 从服务器取回的数据,然后 Javascript 可以很方便的去控制 HTML 页面的显示。同样的思路用在 iframe 方案的客户端,iframe 服务器端并不返回直接显示在页面的数据,而是返回对客户端 Javascript 函数的调用,如“
<script type="text/javascript">js_func(“data from server ”)</script>”。服务器端将返回的数据作为客户端 JavaScript 函数的参数传递;客户端浏览器的 Javascript 引擎在收到服务器返回的 JavaScript 调用时就会去执行代码。
从 图 3 可以看到,每次数据传送不会关闭连接,连接只会在通信出现错误时,或是连接重建时关闭(一些防火墙常被设置为丢弃过长的连接, 服务器端可以设置一个超时时间, 超时后通知客户端重新建立连接,并关闭原来的连接)。
对于iframe长连接,服务器会维护这个长连接,比如说服务器端脚本会使用true循环维持连接,在有数据更新的时候传输代码回客户端执行,形式就如同“
<script type="text/javascript">js_func(“data from server ”)</script>”
使用流解决方案时,浏览器会改善一个完整的HTTP请求,但服务器会发送并保持一个处于打开状态的响应,该响应持续更新并无限期处于打开状态。每当有消息可发送时该响应就会被更新,但服务器永远不会发出响应完成的信号,这样连接会一起保持在打开状态以便后续消息的发送。但是,由于流仍封装在HTTP中,其间防火墙和代理服务器可能会对响应消息进行缓冲,造成消息传递的时延。因此当检测到缓冲代理服务器时,许多流解决方案就回退到长轮询方式。
综上所述,所有这些提供实时数据的方式都会涉及HTTP请求和响应报头,其中包含有大量额外的、不必要的报头数据,会造成传输延迟。最重要的是,全双工连接需要的不仅仅是服务器到客户端的下行连接。为了在半双工HTTP的基础上模拟全双工通信,目前许多解决方案都使用两个连接:一个用于下行数据流,另一个用于上行数据流。这两个连接的保持和协作也会造成大量的资源消耗,并增加了复杂度。
相关文章推荐
- Memcache 安装
- 技术博文 汇总
- ExtJS表单之复选框CheckboxGroup展示与取值
- 转FTP协议详解
- 关于java、Android中Math的一些用法
- 欢迎使用CSDN-markdown编辑器
- leetcode59-Spiral Matrix II(生成蛇形矩阵)
- 回调的原理、实现与应用
- Linux系统信息查看命令
- 音频播放,后台播放,锁频控制
- 光流
- MsSQL的游标的综合运用
- linux下时间同步的两种方法分享
- 博客欣赏
- Android OPenCV 环境配置 <2>
- 返回到顶部代码
- angular.js实现列表orderby排序
- Eclipse 安装FindBugs插件
- 1--1,000,000之间所有的质数
- 解猜数字(XAXB)