HTTP协议是互联网上大量信息交换的基础,其特点是,它是基于请求-响应模式的无状态的单向协议,即,必须由客户端发起一个请求建立连接,服务器接收请 求,把数据返回给客户端,然后释放连接。下一次,再由客户端发起另一次请求,重复上述过程。服务器始终处于"被动"地位。

HTTP协议这一特点,既成就了它的成功,也导致了它的局限性。服务器处理请求的经典模式是一个线程处理一个连接,完了之后,关闭该连接,释放线程以服务 于其他请求。只要响应速度足够快,那么我们可以以相对较少的服务器为数量庞大的用户提供服务。这非常适合于传统的 Web应用,比如:搜索引擎、内容管理系统和电子商务网站等。然而,这种方式并不能满足有实时性要求的应用的需求,很多应用都需要服务器能实时地将更新的 信息传送到客户端,而无须客户端发出请求。例如,新闻标题、证券报价和拍卖行情等。

在Web的早期,人们通过在HTML头部加入META元信息来实现HTML自动刷新。该标记指示浏览器每隔一定的时间间隔刷新一次页面。这不仅带来糟糕的 用户体验,而且是一种低效的做事方式。因为如果没有新的数据,该页面就没必要刷新;如果页面只存在小范围内的变化,该页面就没有必要全部刷新。

AJAX((Asynchronous JavaScript and XML,异步JavaScript和XML))的出现改变了上述情况。Ajax的工作原理相当于在客户和服务器之间加了-个中间层,使客户请求与服务器响 应异步化。并不是所有的请求都提交给服务器,像-些数据验证和数据处理等都交给AJAX引擎自己来做, 只有确定需要从服务器读取新数据时再由AJAX引擎代为向服务器提交请求。使用Ajax的最大优点就是能在不刷新整个页面的前提下维护数据,使得Web应 用程序更为迅捷地响应用户交互,并避免了在网络上发送那些没有改变的信息。然而,AJAX仍然受限于Web请求/响应模式的弱点,使得服务器不能推送实时 动态的Web数据

2、Comet技术实现方式[1]

Comet技术被称为反AJAX(Reverse AJAX )技术,它通过实现服务器推(server push)来解决AJAX需要定时频繁发送请求的问题。通过Comet,客户端所需要的响应信息不再需要主动地去索取,而是在服务器端以事件 (Event)的形式推至客户端。

Comet技术的实现方式有两种:长轮询方式(long-polling)和流方式(streaming)。

长轮询:HTTP的连接保持,服务器端会阻塞请求,直到服务器端有一个事件触发或者到达超时。客户端在收到响应后再次发出请求,重新建立连接。通过这种方 式,服务器可以在数据可用的任何时候将数据"推"到客户端。因为这种方案基于 AJAX,请求异步发出,无须安装插件,IE、Mozilla FireFox 都支持。

流方式: 在流方式中,服务器推数据返回客户端,但不关闭连接,连接始终保持,直到超时,超时后通知客户端重新建立连接,并关闭原来的连接。

在长轮询方式下,客户端是在 XMLHttpRequest 的 readystate 为 4(即数据传输结束)时调用回调函数,进行信息处理。当 readystate 为 4 时,数据传输结束,连接已经关闭。Mozilla Firefox 提供了对流方式的支持,即 readystate 为 3 时(数据仍在传输中),客户端可以读取数据,从而无须关闭连接,就能读取处理服务器端返回的信息。IE 在 readystate 为 3 时,不能读取服务器返回的数据,目前 IE 不支持流方式。

不管是长轮询还是流,请求都需要在服务器上存在一段较长时间,因此Comet被称为"基于HTTP长连接的服务器推技术"。这打破了每个请求一个线程的模 型。这个模型显然对Comet不适用。Java对此提出了非阻塞IO(non-blocking IO)解决方案, Java 通过它的NIO库提供非阻塞IO处理Comet。

传统的阻塞式IO,每个连接必须要开一个线程来处理,您始终从一个线程中读取流直到整个流完成,然后关闭连接。因此阻塞式IO对大量并发的短生命周期连接 不会造成问题。而非阻塞IO处理连接是异步的。当某个连接发送请求到服务器,服务器把这个连接请求当作一个请求"事件",并把这个"事件"分配给相应的函 数处理。我们把这个处理函数放到线程中去执行,执行完就把线程归还。这样一个线程就可以异步地处理多个事件。

为了获得事件通知,我们需要一个机制,它只在需要读时才读,需要写时才写,但又保持连接打开以迅速响应发生的事件。为了方便这个过程,就要用到 NIO,它已是 1.4 版本以后的 JavaTM 语言的一部分。

3、使用Java 开发Comet风格的Web应用

支持Comet 的Java web 开源服务器有Tomcat 6.0.14 和Jetty 6.1.14,它们的实现方法各不相同。下面我们以Tomcat为例来说明开发Comet风格的Web应用的步骤[2]。

本例以流方式实现了一个Comet应用。服务器每隔一定的时间间隔产生一个0~9之间的随机数,将数据推送到客户端。客户端接收并显示。

首先,你要下载和安装Tomcat6.X (到本文撰写的时间,Tomcat最新版本是6.0.24)。

第二,为了使用Comet, 要求服务器支持NIO,所以要修改Tomcat配置文件conf/server.xml, 即启用异步版本的IO连接器,这个非常关键。如下所示:

<Connector connectionTimeout="20000" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443"/>

第三,该项目需要Comet的API支持, Tomcat6自带的Comet API 包为catalina.jar, 在Tomcat安装目录下的lib目录中。

第四,编写Servlet。通过 servlet 实现 CometProcessor 接口。这个接口要求实现 event() 方法,在配置的 Http11NioProtocol 调用 event() 方法来处理请求,而不是 doGet 或 doPost。最基本的支持 Comet 的 servlet 实现如清单 1 所示。

在event() 方法中,分别处理连接开始(BEGIN)、新数据可用(READ),连接结束(END),或出错等事件。Comet 允许针对不同的事件指定不同的连接超时。这意味着可以给常规的请求设置很短的生命周期,但是对于响应长连接请求的机制,可以将这个生命周期延长至几分钟。

TestComet Servlet中,在连接开始时首先设置连接超时为60秒,接着启动一个推送数据的线程。该线程的实现类为 RandomSender,程序如清单 2 所示。请注意,这个类含有一个 ServletResponse 对象。回头看看清单 1 中的 event()方法,当事件为 BEGIN 时,response 对象被传入到 RandomSender中。 RandomSender的 run ()使用 ServletResponse 将数据发送回客户机。因为要实现流风格的 Comet,所以不能关闭连接。而要使连接保持开启。如果要实现长轮询,则一旦发送完所有消息后,就要关闭连接。

第五,编写客户端。在客户端,发出AJAX

程序清单1:Servlet处理 Comet 事件

程序清单2:推送随机数的线程

程序清单3:客户端发送AJAX 请求

请求和常规请求差不多。清单 3 测试了最基本的 AJAX 请求,它基于 XMLHttpRequest ,能够很好地响应来自 Comet 服务器的事件。客户端在readystate 为 3 时(数据仍在传输中)读取数据,从而无须关闭连接,就能读取处理服务器端返回的数据,将它显示在浏览器上。

第六,运行程序。首先进行部署,为了使程序正常运行,先要删除本应用的lib目录下的catalina.jar, 如果不这么做,会出现异常:java.lang.ClassCastException: org.apache.catalina.util.DefaultAnnotationProcessor cannot be cast to org.apache.AnnotationProcessor。

最后,重启Tomcat6,用FireFox浏览器调用主页面index.jsp, 就可以看到随机数不断地涌现。

4、结束语

采用Comet技术实现的Java Web实时系统带来了全新的交互性,目前Java Web 服务器正在为实现 Comet 提供成熟、稳定的技术,不久的将来,Comet将成为Servlet 3.0和JavaEE6的标准的一部分。

文章来源:http://software.intel.com/zh-cn/articles/comet-java-realtime-system-essay/

Comet技术在Java Web中的应用的更多相关文章

  1. Java web中常见编码乱码问题(一)

    最近在看Java web中中文编码问题,特此记录下. 本文将会介绍常见编码方式和Java web中遇到中文乱码问题的常见解决方法: 一.常见编码方式: 1.ASCII 码 众所周知,这是最简单的编码. ...

  2. 深入分析Java Web中的编码问题

    编码问题一直困扰着我,每次遇到乱码或者编码问题,网上一查,问题解决了,但是实际的原理并没有搞懂,每次遇到,都是什么头疼. 决定彻彻底底的一次性解决编码问题. 1.为什么要编码 计算机的基本单元是字节, ...

  3. JDBC在Java Web中的应用

    JDBC在Java Web中的应用 制作人:全心全意 在Java Web开发中,JDBC的应用十分广泛.通常情况下,Web程序操作数据库都是通过JDBC实现,即使目前数据库方面的开源框架层出不穷,但其 ...

  4. Redis(十四)Redis 在Java Web 中的应用

    在传统的 Java Web 项目中,使用数据库进行存储数据,但是有一些致命的弊端,这些弊端主要来自于性能方面. 由于数据库持久化数据主要是面向磁盘,而磁盘的读/写比较慢,在一般管理系统中,由于不存在高 ...

  5. 【中文乱码】深入分析 Java Web 中的中文编码问题

    深入分析 Java Web 中的中文编码问题 1.几种常见的编码格式 1.1 为什么要编码 在计算机中存储信息的最小单元是 1 个字节,即 8 个 bit, 所以能表示的字符范围是 0 ~ 255 个 ...

  6. Java Web 中 过滤器与拦截器的区别

    过滤器,是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法u ...

  7. JAVA WEB 中的编码分析

    JAVA WEB 中的编码分析 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src {background-co ...

  8. Java web中常见编码乱码问题(二)

    根据上篇记录Java web中常见编码乱码问题(一), 接着记录乱码案例: 案例分析:   2.输出流写入内容或者输入流读取内容时乱码(内容中有中文) 原因分析: a. 如果是按字节写入或读取时乱码, ...

  9. 解决java web中safari浏览器下载后文件中文乱码问题

    解决java web中safari浏览器下载后文件中文乱码问题 String fileName = "测试文件.doc"; String userAgent = request.g ...

随机推荐

  1. [Elixir003] Mix Archives

    在[Elixir001]中使用 mix escript.build 生成一个lifelog 的escript启动脚本. 今天我们尝试一下另一种方式:生成Archives. 我们先添加一个Task 1. ...

  2. CheckBox使用记录

    页面显示 页面代码 <div> <div><input type="checkbox" value="" class=" ...

  3. 读取本地json文件,转出为指定格式json

    引用添加Json.Net 引用命名空间 using Newtonsoft.Json //读取自定目录下的json文件 StreamReader sr = new StreamReader(@" ...

  4. sqlserver常用函数

    1.字符串函数 --ascii函数,返回字符串最左侧字符的ascii码值 SELECT ASCII('dsd') AS asciistr --ascii代码转换函数,返回指定ascii值对应的字符 ) ...

  5. org.springframework.dao.CannotAcquireLockException解决

    java.sql.SQLException: Lock wait timeout exceeded 该异常为一个service中调用了另一个service,两个service对同一表进行操作,造成事务 ...

  6. WebService-php- 1(16)

    最近看了挺多关于php中webservice的资料,感谢燕十八的分享,帮助了我构建服务端的过程.将学习笔记记录如下,其中包含燕十八的笔记. WebService 1 快速了解WebService 通俗 ...

  7. J - Judge(快速幂)(同余定理)

    J - Judge   Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Submit S ...

  8. 【OCP题库-12c】最新CUUG OCP 071考试题库(72题)

    72.View the exhibit for the structure of the STUDENTand FACULTYtables. STUDENT Name Null? Type ----- ...

  9. 【OCP 12c】最新CUUG OCP-071考试题库(64题)

    64.(22-7) choose the best answer: View the Exhibit and examine the structure of the ORDERS and ORDER ...

  10. P5282 【模板】快速阶乘算法(多项式运算+拉格朗日插值+倍增)

    题面 传送门 前置芝士 优化后的\(MTT\)(四次\(FFT\)) 题解 这里有多点求值的做法然而被\(shadowice\)巨巨吊起来打了一顿,所以来学一下倍增 成功同时拿到本题最优解和最劣解-- ...