`
zyslovely
  • 浏览: 231545 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

[zz]java实现comet风格(实时更新)

 
阅读更多

[zz]http://chinaxxren.iteye.com/blog/628411
开始
  在本文中,我将展示如何使用各种不同的 Java 技术构建一些简单的 Comet 风格的 Web 应用程序。读者对 Java Servlet、Ajax 和 JavaScript 应该有一定的了解。我们将考察 Tomcat 和 Jetty 中一些支持 Comet 的特性,因此需要使用这两个产品的最新版本。本文使用 Tomcat 6.0.14 和 Jetty 6.1.14。另外还需要一个支持 Java 5 或更高版本的 JDK。本文使用 JDK 1.5.0-16。此外还需要看看 Jetty 7 的预发布版,因为它实现了 Servlet 3.0 规范,我们将在本文中研究该规范。
  理解 Comet
  您可能已经听说过 Comet,因为它最近受到了一定的关注。Comet 有时也称反向 Ajax 或服务器端推技术(server-side push)。其思想很简单:将数据直接从服务器推到浏览器,而不必等到浏览器请求数据。听起来简单,但是如果熟悉 Web 应用程序,尤其是 HTTP 协议,那么您就会知道,这绝不简单。实现 Comet 风格的 Web 应用程序,同时保证在浏览器和服务器上的可伸缩性,这只是在最近几年才成为可能。在本文的后面,我们将看看一些流行的 Java Web 服务器如何支持可伸缩的 Comet 架构,但首先我们来看看为什么要创建 Comet 应用程序,以及用于实现它们的常见设计模式。
  使用 Comet 的动机
  HTTP 协议的成功毋庸置疑。它是 Internet 上大部分信息交换的基础。然而,它也有一些局限性。特别是,它是无状态、单向的协议。请求被发送到 Web 服务器,服务器处理请求并发回一个响应 — 仅此而已。请求必须由客户机发出,而服务器则只能在对请求的响应中发送数据。这至少会影响很多类型的 Web 应用程序的实用性。典型的例子就是聊天程序。另外还有一些例子,例如比赛的比分、股票行情或电子邮件程序。
  HTTP 的这些局限性也是它取得一定成功的原因。请求/响应周期使它成为了经典的模型,即每个连接使用一个线程。只要能够快速为请求提供服务,这种方法就有巨大的 可伸缩性。每秒钟可以处理大量的请求,只需使用少量的服务器就可以处理很大数量的用户。对于很多经典的 Web 应用程序,例如内容管理系统、搜索应用程序和电子商务站点等等而言,这非常适合。在以上任何一种 Web 应用程序中,服务器提供用户请求的数据,然后关闭连接,并释放那个线程,使之可以为其他请求服务。如果提供初始数据之后仍可能存在交互,那么将连接保持为 打开状态,因此线程就不能释放出来,服务器也就不能为很多用户服务。
  但是,如果想在对请求做出响应并发送初始数据之后,仍然保持与用户的交互呢?在 Web 早期,这一点常使用 meta 刷新实现。这将自动指示浏览器在指定秒数之后重新装载页面,从而支持简陋的轮询(polling)。这不仅是一种糟糕的用户体验,而且通常效率非常低下。 如果没有新的数据要显示在页面上呢?这时不得不重新呈现同样的页面。如果对页面的更改很少,并且页面的大部分没有变化呢?同样,不管是否有必要,都得重新 请求和获取页面上的一切内容。
  Ajax 的发明和流行改变了上述状况。现在,服务器可以异步通信,因此不必重新请求整个页面。现在可以进行增量式的更新。只需使用 XMLHttpRequest 轮询服务器。这项技术通常被称作 Comet。这项技术存在一些变体,每种变体具有不同的性能和可伸缩性。我们来看看这些不同风格的 Comet。
  Comet 风格
  Ajax 的出现使 Comet 成为可能。HTTP 的单向性质可以有效地加以规避。实际上有一些不同的方法可以绕过这一点。您可能已经猜到,支持 Comet 的最容易的方式是轮询(poll)。使用 XMLHttpRequest 向服务器发出调用,返回后,等待一段固定的时间(通常使用 JavaScript 的 setTimeout 函数),然后再次调用。这是一项非常常见的技术。例如,大多数 webmail 应用程序就是通过这种技术在电子邮件到达时显示电子邮件的。
  这项技术有优点也有缺点。在这种情况下,您期望快速返回响应,就像任何其他 Ajax 请求一样。在请求之间必须有一段暂停。否则,连续不断的请求会冲垮服务器,并且这种情况下显然不具有可伸缩性。这段暂停使应用程序产生一个延时。暂停的时 间越长,服务器上的新数据就需要越多的时间才能到达客户机。如果缩短暂停时间,又将重新面临冲垮服务器的风险。但是另一方面,这显然是最简单的实现 Comet 的方式。
  现在应该指出,很多人认为轮询并不属于 Comet。相反,他们认为 Comet 是对轮询的局限性的一个解决方案。最常见的 “真正的” Comet 技术是轮询的一种变体,即长轮询(long polling)。轮询与长轮询之间的主要区别在于服务器花多长的时间作出响应。长轮询通常将连接保持一段较长的时间 — 通常是数秒钟,但是也可能是一分钟甚至更长。当服务器上发生某个事件时,响应被发送并随即关闭,轮询立即重新开始。
  长轮询相对于一般轮询的优点在于,数据一旦可用,便立即从服务器发送到客户机。请求可能等待较长的时间,期间没有任何数据返回,但是一旦有了新 的数据,它将立即被发送到客户机。因此没有延时。如果您使用过基于 Web 的聊天程序,或者声称 “实时” 的任何程序,那么它很可能就是使用了这种技术。
  长轮询有一种变体,这是第三种风格的 Comet。这通常被称为流(streaming)。按照这种风格,服务器将数据推回客户机,但是不关闭连接。连接将一直保持开启,直到过期,并导致重新 发出请求。XMLHttpRequest 规范表明,可以检查 readyState 的值是否为 3 或 Receiving(而不是 4 或 Loaded),并获取正从服务器 “流出” 的数据。和长轮询一样,这种方式也没有延时。当服务器上的数据就绪时,该数据被发送到客户机。这种方式的另一个优点是可以大大减少发送到服务器的请求,从 而避免了与设置服务器连接相关的开销和延时。不幸的是,XMLHttpRequest 在不同的浏览器中有很多不同的实现。这项技术只能在较新版本的 Mozilla Firefox 中可靠地使用。对于 Internet Explorer 或 Safari,仍需使用长轮询。
  至此,您可能会想,长轮询和流都有一个很大的问题。请求需要在服务器上存在一段较长的时间。这打破了每个请求使用一个线程的模型,因为用于一个 请求的线程一直没有被释放。更糟糕的是,除非要发回数据,否则该线程一直处于空闲状态。这显然不具有可伸缩性。幸运的是,现代 Java Web 服务器有很多方式可以解决这个问题。
  Java 中的 Comet
  现在有很多 Web 服务器是用 Java 构建的。一个原因是 Java 有一个丰富的本地线程模型。因此实现典型的每个连接一个线程的模型便非常简单。该模型对于 Comet 不大适用,但是,Java 对此同样有解决的办法。为了有效地处理 Comet,需要非阻塞 IO,Java 通过它的 NIO 库提供非阻塞 IO。两种最流行的开源服务器 Apache Tomcat 和 Jetty 都利用 NIO 增加非阻塞 IO,从而支持 Comet。然而,这两种服务器中的实现却各不相同。我们来看看 Tomcat 和 Jetty 对 Comet 的支持。
  Tomcat 和 Comet
  对于 Apache Tomcat,要使用 Comet,主要需要做两件事。首先,需要对 Tomcat 的配置文件 server.XML 稍作修改。默认情况下启用的是更典型的同步 IO 连接器。现在只需将它切换成异步版本,如清单 1 所示。
  清单 1. 修改 Tomcat 的 server.xml
<!-- This is the usual Connector, comment it out and add the NIO  one --> 
  <!-- Connector URIEncoding="utf-8" connectionTimeout="20000"  port="8084" 
protocol="HTTP/1.1" redirectPort="8443"/ --> 
<Connector connectionTimeout="20000" port="8080"  protocol="org.apache. 
coyote.http11.Http11NioProtocol" redirectPort="8443"/> 

Servlet。这显然是 Tomcat 特有的一个接口。清单 2 显示了一个这样的例子。
  清单 2. Tomcat Comet servlet
 
 public class TomcatWeatherServlet extends HttpServlet implements  CometProcessor {
  private MessageSender messageSender = null;
  private static final Integer TIMEOUT = 60 * 1000;
  @Override
  public void destroy() {
  messageSender.stop();
  messageSender = null;
  }
  @Override
  public void init() throws ServletException {
  messageSender = new MessageSender();
  Thread messageSenderThread =
  new Thread(messageSender, "MessageSender[" + getServletContext()
  .getContextPath() + "]");
  messageSenderThread.setDaemon(true);
  messageSenderThread.start();
  }
  public void event(final CometEvent event) throws IOException,  ServletException {
  HttpServletRequest request = event.getHttpServletRequest();
  HttpServletResponse response = event.getHttpServletResponse();
  if (event.getEventType() == CometEvent.EventType.BEGIN) {
  request.setAttribute("org.apache.tomcat.comet.timeout", TIMEOUT);
  log("Begin for session: " + request.getSession(true).getId());
  messageSender.setConnection(response);
  Weatherman weatherman = new Weatherman(95118, 32408);
  new Thread(weatherman).start();
  } else if (event.getEventType() == CometEvent.EventType.ERROR) {
  log("Error for session: " + request.getSession(true).getId());
  event.close();
  } else if (event.getEventType() == CometEvent.EventType.END) {
  log("End for session: " + request.getSession(true).getId());
  event.close();
  } else if (event.getEventType() == CometEvent.EventType.READ) {
  throw new UnsupportedOperationException("This servlet does not accept
  data");
  }
  }
  }
分享到:
评论

相关推荐

    Java 实现 Comet 长连接,服务器主动发送消息给客户端

    Java 实现 Comet 长连接,服务器主动发送消息给客户端是一项关键的技术,它在实时通信、推送服务等领域有着广泛的应用。Comet 是一种基于 HTTP 的持久化连接技术,允许服务器在客户端保持一个打开的 HTTP 连接,直到...

    java-comet

    Java-Comet是一种在Java平台上实现的长轮询(Comet)技术,它主要用于实现实时Web通信。Comet技术允许服务器向客户端推送数据,而不仅仅是响应客户端的请求,这在构建实时应用如聊天室、股票报价、在线游戏等场景中...

    使用Java实现类似Comet风格的web app

    【Java 实现 Comet 风格的 Web App】 在 Web 开发中,Comet 技术是一种实现服务器向客户端实时推送数据的策略,通常被称为“反向 AJAX”或“服务器端推”。它打破了传统的 HTTP 请求-响应模式,使得服务器可以在不...

    java comet服务器推送使用步骤

    Comet4J是一个基于Java的轻量级Comet框架,它能够帮助开发者轻松地实现实时数据推送功能。Comet4J支持多种服务器环境,并且提供了丰富的API接口供开发者调用。通过使用Comet4J,开发者可以专注于业务逻辑的编写,而...

    ssm.rar_comet_java comet_java comet推送_聊天 JAVA SSM

    在这个"ssm.rar_comet_java"压缩包中,我们聚焦于Comet技术在Java环境下的应用,特别是用于实现服务器推送功能,如聊天应用。 Comet是一种Web实时通信技术,它通过持久化HTTP连接使得服务器可以主动向客户端推送...

    java 使用 comet4j 主动向客户端推送信息 简单例子

    综上所述,Java 使用 Comet4j 实现主动向客户端推送信息是通过建立长连接,利用 Comet4j 框架提供的接口和方法来实现实时通信。这个技术在实时聊天、股票行情、在线游戏等需要实时更新信息的场景中有着广泛的应用。

    Servlet3.0 异步处理 页面推送 Comet 实例

    Servlet3.0是Java EE平台中的一个重要更新,它引入了许多新特性,其中一项重大改进就是对异步处理的支持。这项特性使得服务器可以处理长时间运行的任务,而不会阻塞其他请求,提高了系统的响应能力和效率。本实例...

    dwr_comet_im.rar_DEMO_comet.tld_java comet

    在这个"**dwr_comet_im.rar_DEMO_comet.tld_java comet**"的压缩包中,包含了一个关于DWR实现Comet技术的DEMO,以及一个名为"DWR的comet技术实现及时通讯原理.docx"的文档,这将帮助我们理解如何利用DWR和Comet实现...

    tomcat实现comet例子 comet tomcat 随机数

    tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不刷新显示。tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不刷新显示。tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不...

    javaweb实现后台向前台的消息推送 comet4j

    Comet4j是一个专门用于JavaWeb应用的长连接通讯框架,它简化了基于Comet技术的实时通信实现。 首先,我们要理解Comet技术。Comet是一种让服务器端能够长时间保持HTTP连接打开的技术,使得服务器可以在适当的时候向...

    java 使用 comet4j 主动向客户端推送GPS信息的例子

    基于服务器推送框架 Comet4J ,后台模拟实时生成 gps 坐标信息然后再推送到前端页面显示。 如果按照以前的常见方式,我们很可能想到的实现是采用 ajax 前端页面,每隔多长时间向服务器发起一次请求。这是客户端主动...

    浅析Comet技术在Java Web实时系统开发中的应用.pdf

    在Java Web实时系统开发中,Comet技术可以与AJAX技术结合使用,实现实时的数据更新和推送。AJAX技术可以异步地请求服务器端的数据,并将数据更新到客户端,而Comet技术可以实时地将更新的信息传送到客户端。 因此,...

    基于Comet属性同步的Java Web实时进度条研究.pdf

    本文研究了基于Comet属性同步的Java Web实时进度条的实现方案。该方案通过结合Comet技术和Java的反射技术,实现了Java Web实时进度条的处理方式。该方案的优势在于纯Java实现、代码简单、无需安装浏览器插件,并具有...

    comet demo 向客户端推送例子

    总的来说,这个"comet demo"是一个学习和理解Comet技术的绝佳实践,可以帮助开发者掌握如何在Java Web环境中实现服务器向客户端的实时数据推送。通过深入研究和运行这个示例,你可以更好地了解HTTP长连接的工作原理...

    Spring整合DWR comet 实现无刷新 多人聊天室代码整理

    Spring整合DWR(Direct Web Remoting)和Comet技术,是一种高效的实现Web应用程序实时通信的解决方案,特别适用于创建如多人聊天室这样的实时交互应用。在这个项目中,Spring作为后端框架,负责业务逻辑处理和控制...

    DWR+JAVA进行web消息推送dwr-comet.zip

    在DWR中,Comet技术是实现长时间连接和实时数据推送的关键。 首先,我们需要了解Comet技术的基本概念。Comet是一种Web编程模式,用于实现在服务器向客户端推送数据时保持持久连接。传统的HTTP协议是基于请求-响应...

    comet4j简单工程demo

    Comet4j是一个基于Java开发的实时通信框架,主要用于实现服务器向客户端的长连接推送服务。在Web应用中,传统的HTTP协议是请求-响应模式,不利于实现即时消息推送。而Comet4j通过 comet 技术,使得服务器能够主动向...

    comet4j 所需js以及comet4j-tomcat6.jar、comet4j-tomcat7.jar包

    综上所述,这个压缩包包含的`comet4j.js`、`comet4j-tomcat6.jar`和`comet4j-tomcat7.jar`是实现基于Java的Comet4j实时通信框架的关键组件。它们分别负责客户端的JavaScript交互、在Tomcat服务器上的集成和支持,为...

    comet的ajax实现

    comet两种实现之一的ajax实现,内部有源代码,这是一个聊天室的例子

Global site tag (gtag.js) - Google Analytics