1 背景
“服务器推送技术”(Server Pushing)是最近Web技术中最热门的一个流行术语。它是继“Ajax”以后又一个倍受追捧的Web技术。“服务器推送技术”最近的流行跟“Ajax”有着密切的关系。javascript
随着Ajax技术的兴起,让广大开发人员又一次看到了使用浏览器来替代桌面应用的机会,而且此次机会很是大。Ajax将整个页面的刷新变成页面局部的刷新,而且数据的传送是以异步方式进行,这使得网络延迟带来的视觉差别将会消失。php
可是,在浏览器中的Ajax应用中存在一个致命的缺陷没法知足传统桌面系统的需求。那就是“服务器发起的消息传递”(Server-Initiated Message Delivery)。在不少的应用当中,服务器软件须要向客户端主动发送消息或信息。由于服务器掌握着系统的主要资源,可以最早得到系统的状态变化和事件的发生。当这些变化发生的时候,服务器须要主动的向客户端实时的发送消息。例如股票的变化。在传统的桌面系统这种需求没有任何问题,由于客户端和服务器之间一般存在着持久的链接,这个链接能够双向传递各类数据。而基于HTTP协议的Web应用却不行。html
2 客户端获得通知的方式
图1 传统web访问机制java
咱们知道,Web的访问机制天生是设计用来pull数据的,如图1,也就是只容许Browser端主动发起请求,server是被动的响应,不容许Server向Browser发出一个connection请求,也就是说没有为server向Browser push数据提供设计实现.虽然没有直接的实现方法,却可使用一些变通的方式完成相似的功能。web
2.1 传统轮询
在Web早期,这一点常使用meta刷新实现。这将自动指示浏览器在指定秒数以后从新装载页面,从而支持简陋的轮询(polling)。例如在HTML文件中加入<META HTTP-RQUIV="Refresh" CONTENT=12>,实际上就是HTTP头标告知浏览器每12秒更新一次文档。ajax
优势:不须要服务器端的配置。算法
缺点:数据库
a) 糟糕的用户体验编程
b) 对服务器的压力很大,而且形成带宽的极大浪费。浏览器
2.2 Ajax轮询
Ajax隔一段时间(一般使用JavaScript的setTimeout函数)就去服务器查询是否有改变,从而进行增量式的更新。可是间隔多长时间去查询成了问题,由于性能和即时性形成了严重的反比关系。间隔过短,接二连三的请求会冲垮服务器,间隔太长,务器上的新数据就须要越多的时间才能到达客户机。
优势:
a) 不须要太多服务器端的配置。
b) 下降带宽的负荷(由于服务器返回的不是完整页面)。
缺点:
a) 对服务器的压力并不会有明显的减小。
b) 实时性差,有必定的延迟。
应用:这是一项很是常见的技术,例如,大多数webmail应用程序就是经过这种技术在电子邮件到达时显示电子邮件的。
2.3 Comet
Comet方式通俗的说就是一种长链接机制(long lived http)。一样是由Browser端主动发起请求,可是Server端以一种彷佛很是慢的响应方式给出回答。这样在这个期间内,服务器端可使用同一个connection把要更新的数据主动发送给Browser。所以请求可能等待较长的时间,期间没有任何数据返回,可是一旦有了新的数据,它将当即被发送到客户机。Comet又有不少种实现方式,可是总的来讲对Server端的负载都会有增长.虽然对于单位操做来讲,每次只须要建议一次connection,可是因为connection是保持较长时间的,对于server端的资源的占用要有所增长。
优势:实时性好(消息延时小);性能好(能支持大量用户)
缺点:长期占用链接,丧失了无状态高并发的特色。
应用:股票系统、实时通信。
2.4 Flash XML Socket
这种方案实现的基础是:1、Flash提供了XMLSocket类。2、JavaScript 和Flash的紧密结合:在JavaScript能够直接调用Flash程序提供的接口。
缺点:
a) 由于XMLSocket没有HTTP隧道功能,XMLSocket类不能自动穿过防火墙;
b) 由于是使用套接口,须要设置一个通讯端口,防火墙、代理服务器也可能对非 HTTP 通道端口进行限制;
应用:网络聊天室,网络互动游戏。
2.5 Java Applet 套接口
在客户端使用Java Applet,经过java.net.Socket或java.net.DatagramSocket或java.net.MulticastSocket 创建与服务器端的套接口链接,从而实现“服务器推送”。
缺点:须要客户端安装JAVA虚拟机。
3 Comet介绍
Comet 有时也称反向Ajax或服务器端推技术(server-side push)。其思想很简单:将数据直接从服务器推到浏览器,而没必要等到浏览器请求数据。听起来简单,可是若是熟悉 Web 应用程序,尤为是HTTP协议,那么您就会知道,这毫不简单。实现Comet风格的Web应用程序,同时保证在浏览器和服务器上的可伸缩性,这只是在最近几年才成为可能。目前一些主流网站都有相似的原理,例如:webQQ、开心网、校内等等,它们中消息动态都是采用相似的技术,只是具体实现方式不同。
COMET的精髓就在于用服务器与javascript来维持浏览器的长链接,同时完成服务器端事件的浏览器端响应。这样的事件广播机制是跨网络的,同时也是实时的。
采用了Comet技术的服务器在客户机作出一个请求后,和客户机创建一个永久的链接,而后服务器会根据客户机的请求不断把数据包推向客户,这个推的过程是不间断的。由服务器推向客户机的数据在客户机的浏览器上会不断产生新的内容,并且不会产生Client pull那样的HTML文档头,从而大大减小了延迟的时间,向(服务器响应--客户机请求)同步迈进了一步。
服务器推送一般效率要比客户端拖曳效率高,由于它没必要为后续数据创建新的链接。因为始终保持链接,即便没有数据传输时也是这样,所以服务器必须愿意分配这些TCP/IP端口,对于TCP/IP端口数有限的服务器这将是一个严重的问题。
客户端拖曳效率低,由于这必须每次为传送数据创建新的链接。可是它没必要始终保持链接。在实际状况中,创建HTTP链接一般须要花费至关多的时间,多达一秒甚至更多。所以从性能上考虑,服务器推送对于最终用户更有吸引力,特别是对于须要常常更新信息的状况下。
服务器推送相对客户端拖曳的另外一点优点是,服务器推送相对比较容易控制。例如,服务器每一次推送时都保持一个链接,但它又随时能够关闭其中的任何链接,而不须要在服务器上设置特殊的算法。而客户端拖曳在一样的状况下要麻烦许多,它每次要与服务器创建链接,服务器为了处理将客户端拖曳请求与特定的最终用户匹配等状况,须要使用至关麻烦的算法。
如上所述,在服务器推送中,多个响应中链接始终保持,使服务器可在任什么时候间发送更多的数据。一个明显的好处是服务器彻底可以控制更新数据的时间和频率。另外,这种方法效率高,由于始终保持链接。缺点是保持链接状态会浪费服务器端的资源。服务器推送还比较容易中断。
4 Comet实现(Java语言)
4.1 死循环法
最简单的天然是死循环法,若是使用观察者模式则能够进一步提升性能。
可是这种作法的缺点在于客户端请求了这个servlet后,web服务器会开启一个线程执行servlet的代码,而servlet由迟迟不愿结束,形成该线程也没法被释放。因而乎,一个客户端一个线程,当客户端数量增长时,服务器依然会承受很大的负担。
4.2 改写web服务器
目前的趋势是从web服务器内部入手,用nio(JDK 1.4提出的java.nio包)改写request/response的实现,再利用线程池加强服务器的资源利用率,从而解决这个问题,目前支持这一非J2EE官方技术的服务器有Glassfish和Jetty。
JDK 1.4版本(包括以后的版本)最显著的新特性就是增长了NIO(New IO),可以以非阻塞的方式处理网络的请求,这就使得在Java中只须要少许的线程就能处理大量的并发请求了。
Jetty 6设计来处理大量并发链接,它使用Java语言的不堵塞I/O(java.nio)库而且使用优化的输出缓冲架构。Jetty也有一个处理长链接的杀手锏:一个称为Continuations的特性。
Grizzly做为GlassFish中很是重要的一个项目,就是用NIO的技术来实现应用服务器中的高性能纯Java的HTTP引擎。Grizzly仍是一个独立于GlassFish的框架结构,能够单独用来扩展和构建本身的服务器软件。
特色:使用NIO不是一件简单的技术,它的一些特色使得编程的模型比原来阻塞的方式更为复杂。
4.3 使用框架
基于Java的成熟的服务器推送框架有DWR。
DWR是一个开放源码的使用Apache许可协议的解决方案,它包含服务器端Java库、一个DWR servlet以及JavaScript库。虽然DWR不是Java平台上惟一可用的 Ajax-RPC 工具包,可是它是最成熟的,并且提供了许多有用的功能。从最简单的角度来讲,DWR是一个引擎,能够把服务器端Java对象的方法公开给 JavaScript 代码。使用 DWR 能够有效地从应用程序代码中把Ajax的所有请求-响应循环消除掉。这意味着客户端代码不再须要直接处理XMLHttpRequest对象或者服务器的响应。再也不须要编写对象的序列化代码或者使用第三方工具才能把对象变成XML。甚至再也不须要编写servlet代码把Ajax请求调整成对Java域对象的调用。
DWR从2.0开始增长了push功能,也就是在异步传输的状况下能够从Web-Server端发送数据到Browser。
特色:技术成熟,配置简单,DWR与Spring、Struts二、Ext JS都能整合。
5 参考资料
1. DWR中的push机制.pdf(见附件)
2. DWR+EXT JS实现的聊天室(见附件)
3. 其余资料请参考:服务器推送技术博客
服务器推送技术
1.背景
不少应用譬如监控、即时通讯、即时报价系统都须要将后台发生的变化实时传送到客户端而无须客户端不停地刷新、发送请求。本文首先介绍、比较了经常使用的“服务器推”方案,着重介绍了 Comet - 使用 HTTP 长链接、无须浏览器安装插件的两种“服务器推”方案:基于 AJAX 的长轮询方式;基于 iframe 及 htmlfile 的流方式。最后分析了开发 Comet 应用须要注意的一些问题,以及如何借助开源的 Comet 框架-pushlet 构建本身的“服务器推”应用。
传统模式的 Web 系统以客户端发出请求、服务器端响应的方式工做。这种方式并不能知足不少现实应用的需求,譬如:
· 监控系统:后台硬件热插拔、LED、温度、电压发生变化;
· 即时通讯系统:其它用户登陆、发送信息;
· 即时报价系统:后台数据库内容发生变化;
2.两类服务器推技术
这些应用都须要服务器能实时地将更新的信息传送到客户端,而无须客户端发出请求。“服务器推”技术在现实应用中有一些解决方案,本文将这些解决方案分为两类:一类须要在浏览器端安装插件,基于套接口传送信息,或是使用 RMI、CORBA 进行远程调用;而另外一类则无须浏览器安装任何插件、基于 HTTP 长链接。
将“服务器推”应用在 Web 程序中,首先考虑的是如何在功能有限的浏览器端接收、处理信息:
1. 客户端如何接收、处理信息,是否须要使用套接口或是使用远程调用。客户端呈现给用户的是 HTML 页面仍是 Java applet 或 Flash 窗口。若是使用套接口和远程调用,怎么和 JavaScript 结合修改 HTML 的显示。
2. 客户与服务器端通讯的信息格式,采起怎样的出错处理机制。
3. 客户端是否须要支持不一样类型的浏览器如 IE、Firefox,是否须要同时支持 Windows 和 Linux 平台
基于客户端套接口的“服务器推”技术
若是 Web 应用的用户接受应用只有在安装了 Flash 播放器才能正常运行, 那么使用 Flash 的 XMLSocket 也是一个可行的方案。
这种方案实现的基础是:
1. Flash 提供了 XMLSocket 类。
2. JavaScript 和 Flash 的紧密结合:在 JavaScript 能够直接调用 Flash 程序提供的接口。
具体实现方法:在 HTML 页面中内嵌入一个使用了 XMLSocket 类的 Flash 程序。JavaScript 经过调用此 Flash 程序提供的套接口接口与服务器端的套接口进行通讯。JavaScript 在收到服务器端以 XML 格式传送的信息后能够很容易地控制 HTML 页面的内容显示。
关于如何去构建充当了 JavaScript 与 Flash XMLSocket 桥梁的 Flash 程序,以及如何在 JavaScript 里调用 Flash 提供的接口,咱们能够参考 AFLAX(Asynchronous Flash and XML)项目提供的 Socket Demo 以及 SocketJS(请参见 参考资源)。
Javascript 与 Flash 的紧密结合,极大加强了客户端的处理能力。从 Flash 播放器 V7.0.19 开始,已经取消了 XMLSocket 的端口必须大于 1023 的限制。Linux 平台也支持 Flash XMLSocket 方案。但此方案的缺点在于:
1. 客户端必须安装 Flash 播放器;
2. 由于 XMLSocket 没有 HTTP 隧道功能,XMLSocket 类不能自动穿过防火墙;
3. 由于是使用套接口,须要设置一个通讯端口,防火墙、代理服务器也可能对非 HTTP 通道端口进行限制;
不过这种方案在一些网络聊天室,网络互动游戏中已获得普遍使用。
在客户端使用 Java Applet,经过 java.net.Socket 或 java.net.DatagramSocket 或 java.net.MulticastSocket 创建与服务器端的套接口链接,从而实现“服务器推”。
这种方案最大的不足在于 Java applet 在收到服务器端返回的信息后,没法经过 JavaScript 去更新 HTML 页面的内容。
基于 HTTP 长链接的“服务器推”技术(comet)
浏览器做为 Web 应用的前台,自身的处理功能比较有限。浏览器的发展须要客户端升级软件,同时因为客户端浏览器软件的多样性,在某种意义上,也影响了浏览器新技术的推广。在 Web 应用中,浏览器的主要工做是发送请求、解析服务器返回的信息以不一样的风格显示。AJAX 是浏览器技术发展的成果,经过在浏览器端发送异步请求,提升了单用户操做的响应性。但 Web 本质上是一个多用户的系统,对任何用户来讲,能够认为服务器是另一个用户。现有 AJAX 技术的发展并不能解决在一个多用户的 Web 应用中,将更新的信息实时传送给客户端,从而用户可能在“过期”的信息下进行操做。而 AJAX 的应用又使后台数据更新更加频繁成为可能。
图 1. 传统的 Web 应用模型与基于 AJAX 的模型之比较
“服务器推”是一种很早就存在的技术,之前在实现上主要是经过客户端的套接口,或是服务器端的远程调用。由于浏览器技术的发展比较缓慢,没有为“服务器推”的实现提供很好的支持,在纯浏览器的应用中很难有一个完善的方案去实现“服务器推”并用于商业程序。最近几年,由于 AJAX 技术的普及,以及把 IFrame 嵌在“htmlfile“的 ActiveX 组件中能够解决 IE 的加载显示问题,一些受欢迎的应用如 meebo,gmail+gtalk 在实现中使用了这些新技术;同时“服务器推”在现实应用中确实存在不少需求。由于这些缘由,基于纯浏览器的“服务器推”技术开始受到较多关注,Alex Russell(Dojo Toolkit 的项目 Lead)称这种基于 HTTP 长链接、无须在浏览器端安装插件的“服务器推”技术为“Comet”。目前已经出现了一些成熟的 Comet 应用以及各类开源框架;一些 Web 服务器如 Jetty 也在为支持大量并发的长链接进行了不少改进。关于 Comet 技术最新的发展情况请参考关于 Comet 的 wiki。
下面将介绍两种 Comet 应用的实现模型。
基于 AJAX 的长轮询(long-polling)方式
如 图 1 所示,AJAX 的出现使得 JavaScript 能够调用 XMLHttpRequest 对象发出 HTTP 请求,JavaScript 响应处理函数根据服务器返回的信息对 HTML 页面的显示进行更新。使用 AJAX 实现“服务器推”与传统的 AJAX 应用不一样之处在于:
1. 服务器端会阻塞请求直到有数据传递或超时才返回。
2. 客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,从新创建链接。
3. 当客户端处理接收的数据、从新创建链接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端从新创建链接,客户端会一次把当前服务器端全部的信息取回。
一些应用及示例如 “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 属性设为对一个长链接的请求,服务器端就能源源不断地往客户端输入数据。
上节提到的 AJAX 方案是在 JavaScript 里处理 XMLHttpRequest 从服务器取回的数据,而后 Javascript 能够很方便的去控制 HTML 页面的显示。一样的思路用在 iframe 方案的客户端,iframe 服务器端并不返回直接显示在页面的数据,而是返回对客户端 Javascript 函数的调用,如“<script type="text/javascript">js_func(“data from server ”)</script>”。服务器端将返回的数据做为客户端 JavaScript 函数的参数传递;客户端浏览器的 Javascript 引擎在收到服务器返回的 JavaScript 调用时就会去执行代码。
从 图 3 能够看到,每次数据传送不会关闭链接,链接只会在通讯出现错误时,或是链接重建时关闭(一些防火墙常被设置为丢弃过长的链接, 服务器端能够设置一个超时时间, 超时后通知客户端从新创建链接,并关闭原来的链接)。
使用 iframe 请求一个长链接有一个很明显的不足之处: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 浏览器,能够做为参考。(请参见 参考资源)
3.使用 Comet 模型开发本身的应用
上面介绍了两种基于 HTTP 长链接的“服务器推”架构,更多描述了客户端处理长链接的技术。对于一个实际的应用而言,系统的稳定性和性能是很是重要的。将 HTTP 长链接用于实际应用,不少细节须要考虑。
咱们使用 IE 下载文件时会有这样的体验,从同一个 Web 服务器下载文件,最多只能有两个文件同时被下载。第三个文件的下载会被阻塞,直到前面下载的文件下载完毕。这是由于 HTTP 1.1 规范中规定,客户端不该该与服务器端创建超过两个的 HTTP 链接, 新的链接会被阻塞。而 IE 在实现中严格遵照了这种规定。
HTTP 1.1 对两个长链接的限制,会对使用了长链接的 Web 应用带来以下现象:在客户端若是打开超过两个的 IE 窗口去访问同一个使用了长链接的 Web 服务器,第三个 IE 窗口的 HTTP 请求被前两个窗口的长链接阻塞。
因此在开发长链接的应用时, 必须注意在使用了多个 frame 的页面中,不要为每一个 frame 的页面都创建一个 HTTP 长链接,这样会阻塞其它的 HTTP 请求,在设计上考虑让多个 frame 的更新共用一个长链接。
通常 Web 服务器会为每一个链接建立一个线程,若是在大型的商业应用中使用 Comet,服务器端须要维护大量并发的长链接。在这种应用背景下,服务器端须要考虑负载均衡和集群技术;或是在服务器端为长链接做一些改进。
应用和技术的发展老是带来新的需求,从而推进新技术的发展。HTTP 1.1 与 1.0 规范有一个很大的不一样:1.0 规范下服务器在处理完每一个 Get/Post 请求后会关闭套接口链接; 而 1.1 规范下服务器会保持这个链接,在处理两个请求的间隔时间里,这个链接处于空闲状态。 Java 1.4 引入了支持异步 IO 的 java.nio 包。当链接处于空闲时,为这个链接分配的线程资源会返还到线程池,能够供新的链接使用;当原来处于空闲的链接的客户发出新的请求,会从线程池里分配一个线程资源处理这个请求。 这种技术在链接处于空闲的机率较高、并发链接数目不少的场景下对于下降服务器的资源负载很是有效。
可是 AJAX 的应用使请求的出现变得频繁,而 Comet 则会长时间占用一个链接,上述的服务器模型在新的应用背景下会变得很是低效,线程池里有限的线程数甚至可能会阻塞新的链接。Jetty 6 Web 服务器针对 AJAX、Comet 应用的特色进行了不少创新的改进,请参考文章“AJAX,Comet and Jetty”(请参见 参考资源)。
使用长链接时,存在一个很常见的场景:客户端网页须要关闭,而服务器端还处在读取数据的堵塞状态,客户端须要及时通知服务器端关闭数据链接。服务器在收到关闭请求后首先要从读取数据的阻塞状态唤醒,而后释放为这个客户端分配的资源,再关闭链接。
因此在设计上,咱们须要使客户端的控制请求和数据请求使用不一样的 HTTP 链接,才能使控制请求不会被阻塞。
在实现上,若是是基于 iframe 流方式的长链接,客户端页面须要使用两个 iframe,一个是控制帧,用于往服务器端发送控制请求,控制请求能很快收到响应,不会被堵塞;一个是显示帧,用于往服务器端发送长链接请求。若是是基于 AJAX 的长轮询方式,客户端能够异步地发出一个 XMLHttpRequest 请求,通知服务器端关闭数据链接。
在浏览器与服务器之间维持一个长链接会为通讯带来一些不肯定性:由于数据传输是随机的,客户端不知道什么时候服务器才有数据传送。服务器端须要确保当客户端再也不工做时,释放为这个客户端分配的资源,防止内存泄漏。所以须要一种机制使双方知道你们都在正常运行。在实现上:
1. 服务器端在阻塞读时会设置一个时限,超时后阻塞读调用会返回,同时发给客户端没有新数据到达的心跳信息。此时若是客户端已经关闭,服务器往通道写数据会出现异常,服务器端就会及时释放为这个客户端分配的资源。
2. 若是客户端使用的是基于 AJAX 的长轮询方式;服务器端返回数据、关闭链接后,通过某个时限没有收到客户端的再次请求,会认为客户端不能正常工做,会释放为这个客户端分配、维护的资源。
3. 当服务器处理信息出现异常状况,须要发送错误信息通知客户端,同时释放资源、关闭链接。
4.参考资料
学习
· developerWorks 文章“ 面向 Java 开发人员的 Ajax: 使用 Jetty 和 Direct Web Remoting 编写可扩展的 Comet 应用程序”:受异步服务器端事件驱动的 Ajax 应用程序实现较为困难,本文介绍了一种结合使用 Comet 模式和 Jetty 6 Continuations API 的解决方法。
· “Comet: Low Latency Data for the Browser”:Alex Russell 是 Dojo Toolkit 的项目主管和 Dojo Foundation 的主席,他在这篇博客文章中提出了 Comet 这个术语。
· “What else is burried down in the depth’s of Google’s amazing JavaScript?”(Alex Russel,2006 年 2 月):Alex 在这篇文章里介绍了如何使用“htmlfile”ActiveX 控件解决 iframe 请求长链接时 IE 的加载显示问题。
· Comet wiki:提供了不少开源 Comet 框架的连接。
· Jetty:Jetty 是一种开源的基于标准的 Web 服务器,彻底使用 Java 语言实现。
· “Ajax, Comet and Jetty”(Greg Wilkins,Webtide,2006 年 1 月):Wilkins 的这份白皮书讨论了扩展 Ajax 链接的 Jetty 架构方法。
· Continuations:了解更多关于 Jetty 的 Continuations 特性的信息。
· “pushlet”:开源 comet 框架,使用了观察者模型。浏览器端提供了基于 AJAX 和 iframe 的 JavaScript 库,服务器端使用 Java Servlet。
· “How to implement COMET with PHP”:提供的 comet-iframe.tar.gz 使用 iframe/htmlfile 封装了一个 JavaScript comet 对象,支持 IE、Mozilla Firefox 浏览器。
· “AFLAX”:Asynchronous Flash and XML,提供了强大的 Flash、Javascript 库和不少范例。
· developerWorks Ajax 技术资源中心:能找到更多关于 Ajax 技术的文章和教程。
· developerWorks Web 开发技术专区:提供了关于 Web 开发和架构方面的大量文章。
· developerWorks Java 技术专区:提供了关于 Java 编程各个方面的数百篇文章。
· 浏览 技术书店,查阅有关本文所述主题以及其余技术主题的书籍。
得到产品和技术
· Jetty:下载 Jetty。
讨论
· 查看 developerWorks blogs,加入 developerWorks 社区。
周婷,软件工程师,目前在 IBM 中国软件开发技术实验室从事刀片服务器管理固件的开发工做。您能够经过 zhouting@cn.ibm.com 和她联系。
原文连接:http://www.ibm.com/developerworks/cn/web/wa-lo-comet/#resources
Pushlet -开源 Comet 框架
Pushlet 是一个开源的 Comet 框架,在设计上有不少值得借鉴的地方,对于开发轻量级的 Comet 应用颇有参考价值。
观察者模型
Pushlet 使用了观察者模型:客户端发送请求,订阅感兴趣的事件;服务器端为每一个客户端分配一个会话 ID 做为标记,事件源会把新产生的事件以多播的方式发送到订阅者的事件队列里。
客户端 JavaScript 库
pushlet 提供了基于 AJAX 的 JavaScript 库文件用于实现长轮询方式的“服务器推”;还提供了基于 iframe 的 JavaScript 库文件用于实现流方式的“服务器推”。
JavaScript 库作了不少封装工做:
1. 定义客户端的通讯状态:STATE_ERROR、STATE_ABORT、STATE_NULL、STATE_READY、STATE_JOINED、STATE_LISTENING;
2. 保存服务器分配的会话 ID,在创建链接以后的每次请求中会附上会话 ID 代表身份;
3. 提供了 join()、leave()、subscribe()、 unsubsribe()、listen() 等 API 供页面调用;
4. 提供了处理响应的 JavaScript 函数接口 onData()、onEvent()…
网页能够很方便地使用这两个 JavaScript 库文件封装的 API 与服务器进行通讯。
客户端与服务器端通讯信息格式
pushlet 定义了一套客户与服务器通讯的信息格式,使用 XML 格式。定义了客户端发送请求的类型:join、leave、subscribe、unsubscribe、listen、refresh;以及响应的事件类型:data、join_ack、listen_ack、refresh、heartbeat、error、abort、subscribe_ack、unsubscribe_ack。
服务器端事件队列管理
pushlet 在服务器端使用 Java Servlet 实现,其数据结构的设计框架仍可适用于 PHP、C 编写的后台客户端。
Pushlet 支持客户端本身选择使用流、拉(长轮询)、轮询方式。服务器端根据客户选择的方式在读取事件队列(fetchEvents)时进行不一样的处理。“轮询”模式下 fetchEvents() 会立刻返回。”流“和”拉“模式使用阻塞的方式读事件,若是超时,会发给客户端发送一个没有新信息收到的“heartbeat“事件,若是是“拉”模式,会把“heartbeat”与“refresh”事件一块儿传给客户端,通知客户端从新发出请求、创建链接。
客户服务器之间的会话管理
服务端在客户端发送 join 请求时,会为客户端分配一个会话 ID, 并传给客户端,而后客户端就经过此会话 ID 标明身份发出 subscribe 和 listen 请求。服务器端会为每一个会话维护一个订阅的主题集合、事件队列。
服务器端的事件源会把新产生的事件以多播的方式发送到每一个会话(即订阅者)的事件队列里。
本文介绍了如何在现有的技术基础上选择合适的方案开发一个“服务器推”的应用,最优的方案仍是取决于应用需求的自己。相对于传统的 Web 应用, 目前开发 Comet 应用仍是具备必定的挑战性。
“服务器推”存在普遍的应用需求,为了使 Comet 模型适用于大规模的商业应用,以及方便用户构建 Comet 应用,最近几年,不管是服务器仍是浏览器都出现了不少新技术,同时也出现了不少开源的 Comet 框架、协议。需求推进技术的发展,相信 Comet 的应用会变得和 AJAX 同样普及。