初识Comet技术

一、服务器推送技术概述
服务器推送技术(Servers Push)的基础思想是将浏览器主动查询信息改为服务器主动发送信息。服务器发送一批数据,浏览器显示这些数据,同时保证与服务器的连接。当服务器需要再次发送一批数据时,浏览器显示数据并保持连接。以后,服务器仍然可以发送批量数据,浏览器继续显示数据,依次类推 。主要应用于:
  • 监控系统:报警提示;
  • 即时通信系统:其它用户登录、发送信息;
  • 即时报价系统:后台数据库内容发生变化; 
  • 实现基于web的实时事件通知 。
实现方式有:
  • 基于客户端套接口 : 采用RMI、CORBA或者自定义TCP/IP信息的applet来实现
  • Comet: 基于 HTTP 长连接、无须在浏览器端安装插件的技术

1.传统轮询

在Web早期,这一点常使用meta刷新实现。这将自动指示浏览器在指定秒数之后重新装载页面,从而支持简陋的轮询(polling)。例如在HTML文件中加入<META HTTP-RQUIV="Refresh" CONTENT=12>,实际上就是HTTP头标告知浏览器每12秒更新一次文档。

  • 优点:不需要服务器端的配置。
  • 缺点:a)  糟糕的用户体验; b) 对服务器的压力很大,并且造成带宽的极大浪费。

2. Ajax轮询

Ajax隔一段时间(通常使用JavaScript的setTimeout函数)就去服务器查询是否有改变,从而进行增量式的更新。但是间隔多长时间去查询成了问题,因为性能和即时性造成了严重的反比关系。间隔太短,连续不断的请求会冲垮服务器,间隔太长,务器上的新数据就需要越多的时间才能到达客户机。

  • 优点:a)  不需要太多服务器端的配置。b) 降低带宽的负荷(因为服务器返回的不是完整页面)。
  • 缺点:a) 对服务器的压力并不会有明显的减少。b) 实时性差,有一定的延迟。
  • 应用:这是一项非常常见的技术,例如,大多数webmail应用程序就是通过这种技术在电子邮件到达时显示电子邮件的。

二、Comet

Comet是一种用于web的 推送技术,能使服务器能实时地将更新的信息传送到客户端,而无须客户端发出请求,

Comet 有时也称反向Ajax或服务器端推技术(server-side push)。其思想很简单:将数据直接从服务器推到浏览器,而不必等到浏览器请求数据。听起来简单,但是如果熟悉 Web 应用程序,尤其是HTTP协议,那么您就会知道,这绝不简单。实现Comet风格的Web应用程序,同时保证在浏览器和服务器上的可伸缩性,这只是在最近几年才成为可能。目前一些主流网站都有类似的原理,例如:webQQ、开心网、校内等等,它们中消息动态都是采用类似的技术,只是具体实现方式不一样。

COMET的精髓就在于用服务器与javascript来维持浏览器的长连接,同时完成服务器端事件的浏览器端响应。这样的事件广播机制是跨网络的,同时也是实时的。

采用了Comet技术的服务器在客户机做出一个请求后,和客户机建立一个永久的连接,然后服务器会根据客户机的请求不断把数据包推向客户,这个推的过程是不间断的。由服务器推向客户机的数据在客户机的浏览器上会不断产生新的内容,而且不会产生Client pull那样的HTML文档头,从而大大减少了延迟的时间,向(服务器响应--客户机请求)同步迈进了一步。

服务器推送通常效率要比客户端拖曳效率高,因为它不必为后续数据建立新的连接。由于始终保持连接,即使没有数据传输时也是这样,因此服务器必须愿意分配这些TCP/IP端口,对于TCP/IP端口数有限的服务器这将是一个严重的问题。

客户端拖曳效率低,因为这必须每次为传送数据建立新的连接。但是它不必始终保持连接。在实际情况中,建立HTTP连接通常需要花费相当多的时间,多达一秒甚至更多。因此从性能上考虑,服务器推送对于最终用户更有吸引力,特别是对于需要经常更新信息的情况下。

服务器推送相对客户端拖曳的另一点优势是,服务器推送相对比较容易控制。例如,服务器每一次推送时都保持一个连接,但它又随时可以关闭其中的任何连接,而不需要在服务器上设置特殊的算法。而客户端拖曳在同样的情况下要麻烦许多,它每次要与服务器建立连接,服务器为了处理将客户端拖曳请求与特定的最终用户匹配等情况,需要使用相当麻烦的算法。

如上所述,在服务器推送中,多个响应中连接始终保持,使服务器可在任何时间发送更多的数据。一个明显的好处是服务器完全能够控制更新数据的时间和频率。另外,这种方法效率高,因为始终保持连接。缺点是保持连接状态会浪费服务器端的资源。服务器推送还比较容易中断。

Comet目前有两种实现方式,长轮询和iframe流。
  • 基于AJAX长轮询(long-polling)——长轮询是在打开一条连接以后保持,等待服务器推送来数据再关闭的方式。即服务端阻断前一次对客户端的回应,在事件发生后将事件内容绑定在回应中返回给客户端,同时回应结束,此时客户端立即发送第二次请求,服务器阻塞回应等待下一次事件发生。
  • 基于iframe及htmlfile流的方式——iframe流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间建立一条长链接,服务器向iframe传输数据(通常是HTML,内有负责插入信息的javascript),来实时更新页面。  iframe流方式的优点是浏览器兼容好,Google公司在一些产品中使用了iframe流,如Google Talk
  • 优点:实时性好(消息延时小);性能好(能支持大量用户)

    缺点:长期占用连接,丧失了无状态高并发的特点

1、基于AJAX轮询方式与传统AJAX方式的区别:

    1). 服务器端会阻塞请求直到有数据传递或超时才返回。
    2). 客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
    3). 当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。

    采用这种方式实现的技术有meboo和pushlet chat。

2、基于iframe及htmlfile流的方式

    这个方式和AJAX方式原理相同,只是浏览器一直会显示正在连接状态,gtalk采用htmlfile技术解决了此问题。Zeitoun 网站提供的 comet-iframe.tar.gz,封装了一个基于 iframe 和 htmlfile 的 JavaScript comet 对象,支持 IE、Mozilla Firefox 浏览器,可以作为参考:http://www.zeitoun.net/articles/comet_and_php/start

3、Http长连接的编程原则

    1)、不要在同一个客户端开启超过两个的http长连接,这个是受http协议限制的。
    2)、控制信息和数据信息使用不同的http连接。
    3)、在客户端和服务器端保持“心跳”信息。

4、Pushlet框架学习

    Pushlet框架是用后台采用java实现,前台技术有AJAX和Iframe两种。设计思想采用观察者模式。

三、实现了comet的相关开源框架

  • pushlet——通过servlet(或者JSP)把JavaScript代码作为HTTP流推送到浏览器。这些代码被浏览器的JavaScript引擎解释并完成一些有趣的工作。于是便轻松地完成了从server端的Java到浏览器中的JavaScript的回调。
  • dwr
  • cometD

四、Comet实现(Java语言)

1   死循环法

最简单的自然是死循环法,如果使用观察者模式则可以进一步提高性能。

但是这种做法的缺点在于客户端请求了这个servlet后,web服务器会开启一个线程执行servlet的代码,而servlet由迟迟不肯结束,造成该线程也无法被释放。于是乎,一个客户端一个线程,当客户端数量增加时,服务器依然会承受很大的负担。

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不是一件简单的技术,它的一些特点使得编程的模型比原来阻塞的方式更为复杂。

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、Struts2、Ext JS都能整合。

参考:

你可能感兴趣的:(Comet)