现在的位置: 首页 > 综合 > 正文

Comet简介

2013年10月07日 ⁄ 综合 ⁄ 共 5322字 ⁄ 字号 评论关闭

Comet概述... 2

定义... 2

典型应用场景... 3

浏览器端兼容性... 3

可靠性... 4

可扩展性... 4

注意事项... 4

其他解决方案... 5

CometAjax的区别... 5

NIO.. 7

对比... 7

支持... 9

性能对比... 9

A项目中Comet的使用... 10

DojoBayeux简介... 11

备注... 11

Multipart/x-mixed-replace示例... 11

Pushlet简介... 12

参考资料... 13

Comet讨论... 13

进阶资料... 15

 

 


Comet概述

定义

Comet是基于Http长连接的新一代互联网技术,对其较早的定义来自http://alex.dojotoolkit.org/?p=545

 

要讲Comet,先从Server Push开始。

Server Push是一种很早就存在的技术,以前在实现上主要是通过客户端的套接字,或是服务器端的远程调用。因为浏览器技术的发展比较缓慢,没有为Server Push的实现提供很好的支持,在纯浏览器的应用中很难有一个完善的方案去实现Server Push并用于商业程序。最近几年,因为 AJAX 技术的普及,以及把 IFrame 嵌在“htmlfile“的 ActiveX 组件中可以解决 IE 的加载显示问题,一些受欢迎的应用如 meebogmail+gtalk 在实现中使用了这些新技术;同时“服务器推”在现实应用中确实存在很多需求。因为这些原因,基于纯浏览器的“服务器推”技术开始受到较多关注,Alex RussellDojo Toolkit 的项目 Lead)称这种基于 HTTP 长连接、无须在浏览器端安装插件的Server Push技术为“Comet”。目前已经出现了一些成熟的 Comet 应用以及各种开源框架;一些 Web 服务器如 Jetty 也在为支持大量并发的长连接进行了很多改进。关于 Comet 技术最新的发展状况请参考关于 Comet wiki.

 

Wikipedia上对Comet的定义如下:

Comet is a World Wide Web application architecture in which a web server sends data to a client program (normally a web browser) asynchronously without any need for the client to explicitly request it. It allows creation of event-driven web applications, enabling real-time interaction otherwise impossible in a browser. Though the term Comet was coined in 2006,the idea is several years older, and has been called various names, including server push, HTTP push, HTTP streaming, Pushlets, Reverse Ajax, and others.

Comet applications use long-lived HTTP connections between the client and server, which the server can respond to lazily, pushing new data to the client as it becomes available. This differs from the original model of the web, in which a browser receives a complete web page in response to each request, and also from the Ajax model, in which browsers request chunks of data, used to update the current page. The effect is similar to applications using traditional Ajax with polling to detect new information on the server, but throughput is improved and latency and server load are decreased.

Comet does not refer to any specific technique for achieving this user-interaction model, but encompasses all of them—though it implies the use of browser-native technologies such as JavaScript as opposed to proprietary plugins. Several such techniques exist, with various trade-offs in terms of browser support and side effects, latency, and throughput.

 

传统的web应用都是基于请求-响应的模式,ajax的改进只是非全页面更新,无法解决实时性和事件驱动。ajax with polling通过定时请求可以实现伪实时,但频繁的建立和销毁连接又会耗费服务器大量资源,增加带宽使用。Comet使用Http1.1 长连接,实现实时的服务器-客户端数据推送。Comet的实现可以有两种方式,StreamingLong-PollingStreaming方式建立连接后,两端均不断开,使用此连接实时传输消息。Long-Polling方式一旦完成数据接收,即断开当前连接并重新建立新连接。二者相比Streaming性能最优,但即使是Long-Polling,不管是服务端负载还是对网络带宽的使用,也大大优于传统的Polling

典型应用场景

Comet特别适用于需要和服务器端实时交互的应用,如聊天,远程协作等类型的Web应用。

浏览器端兼容性

Comet之前,可通过下述途径来实现类似的效果,其中部分方式现在仍有较多使用。各方式对浏览器端的兼容性如下:

1.     IFrame

最早的实现方式,通过隐藏的IFrame元素实现对服务器的持续请求,在返回内容中输出并执行JavaScript以实现。优点是基本所有浏览器都支持,缺点是会导致部分浏览器的状态条一直为读取状态且鼠标状态为忙碌,影响用户体验。

2.     Htmlfile ActiveX object

通过将HTML IFrame元素置于一个ActiveX中,规避了1中所提到的两个缺点。其缺点很显然,仅IE支持,如Google Gtalk。另外Zeitouncomet-iframe将提供Javascript对象支持内嵌IFrame,支持IE,FF

3.     Multipart XHR(XMLHttpRequest)

1995年,Netscape中增加了一个特性叫Server Push,这个特性允许服务器端在同一个Http Response中发送图片或HTML页的新版本到浏览器端,通过在HTML头声明ContentTypemultipart/x-mixed-replace实现,浏览器会使用新版本的HTML替换已有页面。不过这个特性仅在使用Gecko内核的浏览器中支持。

4.     XHR streaming

通过自定义返回数据格式,在浏览器端捕获onreadystatechange 事件并在readyState=3时回调对应JavaScript方法来处理数据并实现。此方式IE不可行。

5.     XHR long polling

上述若干方法兼容性都不是很好,而XHR long polling在所有支持XHR的浏览器中都可以使用。其实现方式为:浏览器建立一个异步连接,当服务器响应后回调JS方法,然后重新建立新的连接并等待服务器端下一次响应。

6.     Dynamic script tag long polling

该方式更好解决跨域调用问题,虽然跨域页面的互操作也可以通过代理来解决。

7.     Server-sent events

HTML5草案中的新元素event source

 

可靠性

代理服务器和防火墙可能对Comet应用有不利影响。一般防火墙都会断开已建立时间过长的连接。大多数Comet框架的解决办法是重建连接。

另外,代理服务器可能缓存被推送的数据,使应用丧失实时性。

可扩展性

因为Comet应用实时发送服务器端事件,一般会比其他的传统web应用消耗更多资源,使得其扩展性相对较差。

首先,Comet应用需要在服务器和浏览器间维持至少一个长连接,而传统的web服务器按照页面-页面请求进行的设计和优化使其在无法在同一时间维持如此多的连接。这导致Comet应用无法在一个web server上处理大量请求,垂直扩展性差。

垂直扩展性差的原因在于传统的web serverApache等的处理线程使用同步IO。每个请求被分配一个线程去处理,并尽可能尽快处理完毕并关闭连接以处理下一个请求。但Comet应用建立的连接是持久的,处理请求的每个线程不能用于处理其他请求,如果有大量长连接建立,web server就可能无法处理新发起的请求。

JettyTomcatWeb应用服务器已为Comet应用进行优化(ContinuationServlet, 但是因为不是标准的servlet实现,不具备服务器兼容性),使用异步IO(JDK5之后)来处理长连接,一定数目的线程去轮询各个连接并在到达每个连接时将所需数据推送到浏览器端。此类服务器不仅可以处理比线程服务器多的多的长连接,而且随着连接数增加,处理延迟被均摊到每个连接,对用户影响小。值得注意的是,sun新提交的JSR315 servlet3.0也包括了comet,今后将成为J2EE服务器的标准实现。

另外,一般Comet应用都是交互性的,允许多用户间通讯,因此将处理任务分派到多个server去处理有困难。即水平扩展性差。

对水平扩展性的一种解决方式是按照事件对服务器进行分组,将订阅某组事件的请求转发到指定的服务器上。

注意事项

1.     HTTP1.1标准中有如下规定:“A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy,并且此规则被包括IEFF在内的绝大多数浏览器遵守。因此,当comet占用一个http长连接,将可能导致浏览器不能为ajax请求创建新的连接,比如浏览器正在读取大量图片时。

2.     如果有新的公共数据需要push,所有servlet要同时将数据push出去,在push之前还会有查询,这样对cpu内存和网络都会有较大消耗,而且是同时的,会造成共振效应。
可以考虑使用一个公共的查询线程来负责,request被放入一个队列,查询线程负责轮询所有request,来将各自需要的数据pushclient,这样可以响应的并发连接数可能会多很多,且避免了共振。

其他解决方案

鉴于浏览器对Comet的直接支持较差,有部分开发者使用了flashjava applet等浏览器插件来实现实时响应。只要安装了相应插件,该方式不用考虑浏览器的差异,通用性较好,且不用占用HTTP连接。

 

CometAjax的区别

请见下图。


 

NIO

对比

JettyContinousServlet(使用NIO)和标准Servlet性能对比来说明:

 

代码段I:BlockingServlet(未使用NIO)

               

public class BlockingServlet extends HttpServlet {

 

  public void service(HttpServletRequest req, HttpServletResponse res)

                                              throws java.io.IOException {

 

    String reqId = req.getParameter("id");

   

    res.setContentType("text/plain");

    res.getWriter().println("Request: "+reqId+"/tstart:/t" + new Date());

    res.getWriter().flush();

 

    try {

      Thread.sleep(2000);

    } catch (Exception e) {}

   

    res.getWriter().println("Request: "+reqId+"/tend:/t" + new Date());

  }

}

 

现在可以观察到 servlet 响应一些同步请求的行为。展示了控制台输出,五个使用 lynx 的并行请求。命令行启动五个 lynx 进程,将标识序号附加在请求 URL 的后面。

 

输出I: BlockingServlet 并发请求的输出:               

抱歉!评论已关闭.