- 浏览: 1334367 次
- 性别:
- 来自: 成都
文章分类
- 全部博客 (471)
- 原创文章 (4)
- Database (84)
- J2SE (63)
- Web (26)
- Javascript (30)
- Lucene (11)
- os (13)
- 算法 (8)
- Webservice (1)
- Open projects (18)
- Hibernate (18)
- Spring (15)
- Css (2)
- J2ee (2)
- 综合技术 (18)
- 安全管理 (13)
- PatternsInJava (27)
- NIO (5)
- Ibatis (2)
- 书籍收藏 (1)
- quartz (7)
- 并发编程 (15)
- oracle问题 (2)
- ios (60)
- coco2d-iphone (3)
- C++ (6)
- Zookeeper (2)
- golang (4)
- animation (2)
- android (1)
最新评论
-
dandingge123:
【引用】限制UITextField输入长度的方法 -
qja:
...
对List顺序,逆序,随机排列实例代码 -
安静听歌:
现在在搞这个,,,,,哎~头都大了,,,又freemarker ...
通用大型网站页面静态化解决方案(一) -
springdata-jpa:
java quartz定时任务demo教程源代码下载,地址:h ...
Quartz 配置参考 -
马清天:
[b][/b][list][*]引用[u][/u][/list ...
通用大型网站页面静态化解决方案(一)
开始
在本文中,我将展示如何使用各种不同的 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");
}
}
}
评论
我运行了一下只跳出来一次对话框就结束了。
发表评论
-
JavaScript初学者应注意的七个细节
2011-01-16 22:34 1112每种语言都有它特别的地方,对于JavaScript来说,使 ... -
META功能总结
2011-01-07 21:13 4665一、META的作用: meta标签通常用来为搜索引擎ro ... -
修改tomcat6配置,快速实现主域名、二级域名之间session共享
2010-12-02 22:04 2980项目中遇到了每个用户一个二级域名的应用,但在主域名登录后,在 ... -
实践中整理出tomcat集群和负载均衡
2010-11-25 23:33 1177(一)环境说明 (1)服务器有4台,一台安装apac ... -
httpsession的原理及负载均衡
2010-11-15 12:06 13564前阵子去面试正好被问到httpsession和cookie,今 ... -
Apache负载均衡+Tomcat集群
2010-10-26 21:56 1417核心提示:目标 : 使用 apache 和 tomcat ... -
Spring Ldap 域认证
2010-10-26 21:17 4499核心提示:近段时间接触了一个项目,用户认证部分是通过域认证 ... -
Spring + Tomcat 中配置连接池
2010-10-26 21:12 4850核心提示:Tomcat5 及 Tomcat6 下CP配置。 主 ... -
基于总线的消息服务(BBMS)的设计与实现
2010-10-26 21:09 2595核心提示:前言 异步事件的通知机制在比较有规模的软件设计中 ... -
JSON --- JAVA 使用方法
2010-10-25 22:51 1167JSON 即 JavaScript Object Natati ... -
大型门户网站架构分析
2010-10-24 15:48 5197千万人同时访问的网站,一般是有很多个数据库同时工作,说明白一点 ... -
fck config
2010-10-19 10:48 1531写道 * * FCKeditor - The text ... -
功能强大的fck编辑器(完整详解)
2010-10-19 10:39 3718一直都没找到完整的Fck ... -
ORACLE中的ROWID
2010-10-14 16:36 10981、rowid是一个伪列,是用来确保表中行的唯一性,它 ... -
FCKeditor在线编辑器
2010-10-14 16:20 1572FCKeditor在线编辑器 FCKeditor 这个开源 ... -
用java获取真实的ip地址
2010-10-14 16:18 2195在JSP里,获取客户端的IP地址的方法是:reques ... -
实践中整理出tomcat集群和负载均衡
2010-10-14 15:50 1159实践中整理出tomcat集群 ... -
关于MapleFetion
2010-07-28 17:40 1833http://code.google.com/p/maplef ... -
jfreechart
2010-06-28 18:13 1455http://dev.firnow.com/course/3_ ... -
Java中如何实现Comet风格的Web应用(二)
2010-03-30 17:00 2854CometProcessor 接口要求实现 event 方法 ...
相关推荐
Java-Comet是一种在Java...总结,Java-Comet技术是Java环境中实现服务器向客户端实时推送数据的一种方法,尤其适用于需要实时交互的Web应用。通过理解和掌握Java-Comet,开发者可以创建出更高效、响应更快的Web服务。
在 Java 中实现 Comet,我们可以利用 Servlet API 和 WebSocket API。Servlet API 提供了处理 HTTP 请求的能力,而 WebSocket 则是 HTML5 引入的一种双向通信协议,支持服务器主动发送数据。 1. **使用 Servlet ...
要使用 Java 实现类似 Comet 风格的 Web 应用,你需要对以下几个关键知识点有所了解: 1. **HTTP 协议的限制**: - HTTP 协议是基于请求-响应模型的,意味着客户端(浏览器)需要先发送请求,服务器才能响应。 - ...
Comet4J是一个实现了Comet技术的Java框架,它简化了在Java应用中实现服务器推送的复杂性。使用Comet4J,开发者可以创建服务端的推送通道,通过这些通道,服务器能够将数据高效地推送到多个客户端。Comet4J提供了多种...
Comet技术是Java Web实时系统开发中的关键技术之一,它通过实现服务器推送(Server Push)来解决AJAX需要定时频繁发送请求的问题。Comet技术有两种实现方式:长轮询方式(Long Pollling)和流方式(Streaming)。 ...
在传统的HTTP协议中,服务器只能在客户端发起请求时发送数据,而Comet通过长时间保持一个HTTP连接开放,使得服务器可以在需要时主动推送数据,极大地增强了Web应用的实时性。 在Servlet3.0之前,实现Comet技术通常...
在这个"ssm.rar_comet_java"压缩包中,我们聚焦于Comet技术在Java环境下的应用,特别是用于实现服务器推送功能,如聊天应用。 Comet是一种Web实时通信技术,它通过持久化HTTP连接使得服务器可以主动向客户端推送...
Comet技术,全称为“Comet Web应用”,是一种在Web开发中实现服务器向客户端推送数据的技术,也被称为反向Ajax或服务器端推送。这种技术打破了传统的HTTP请求/响应模式,使得服务器可以在客户端未发起新请求时主动...
Comet技术在IT领域中扮演着独特角色,它是一种颠覆传统HTTP请求-响应模式的Web应用开发方法。在传统的HTTP交互中,客户端(浏览器)向服务器发送请求,服务器处理请求并返回响应,然后连接关闭。然而,Comet打破了这...
以上就是使用Comet4j在JavaWeb项目中实现后台消息推送的基本流程。在实际应用中,可能还需要考虑连接管理、错误处理、性能优化等问题。通过这个例子,你可以了解到Comet4j如何帮助开发者构建实时的、双向通信的Web...
Comet是一种Web交互模式,它允许服务器向客户端推送数据,而不仅仅是响应客户端请求,从而实现更实时的Web应用体验。 **Jetty服务器**: Jetty是一款轻量级、开源的HTTP服务器和Servlet容器,广泛用于Java Web应用...
Comet作为一种实现服务器向客户端推送数据的技术方案,在早期的Web应用中扮演了重要的角色。Java Comet框架为开发者提供了一种简单而有效的方式来实现这一功能。本文将详细介绍如何使用Comet4J框架来实现Java Comet...
在本文中,我们将深入探讨如何使用DWR(Direct Web Remoting)与Java技术结合实现Web消息推送功能。DWR是一种JavaScript库,它允许在浏览器和服务器之间进行实时、双向通信,为Web应用提供了类似AJAX的功能,但更加...
综上所述,这个压缩包提供了DWR实现Comet技术的一个实践示例,可以帮助开发者理解如何在Java Web应用中构建即时通讯功能。通过学习和分析这个DEMO,我们可以掌握如何配置DWR,使用comet.tld标签库,以及编写客户端和...
"我的示例"(MyDemo)可能是包含在压缩包中的一个实际应用案例,展示了如何使用这个Comet框架来实现Web即时通讯。这个例子可能包括服务器端代码和客户端JavaScript代码,通过创建连接、发送和接收消息,以及处理推送...
Comet技术是为了解决Java Web实时系统中服务器推送数据到客户端的问题,它克服了HTTP协议的请求-响应模式的局限性。在传统的HTTP模式下,客户端必须发起请求才能获取服务器的数据,而在实时系统中,如新闻更新、股票...
总的来说,这个"comet demo"是一个学习和理解Comet技术的绝佳实践,可以帮助开发者掌握如何在Java Web环境中实现服务器向客户端的实时数据推送。通过深入研究和运行这个示例,你可以更好地了解HTTP长连接的工作原理...
在Java Web环境中,使用Comet技术通常需要结合Servlet或WebSocket等技术。长轮询方式利用Servlet的生命周期,服务器接收到请求后保持连接,直到有新数据或超时才返回响应。流方式则可能需要更底层的控制,如使用...
本文的研究结果表明,基于Comet属性同步的Java Web实时进度条的处理方案是一个可行的解决方案,它具有纯Java实现、代码简单、无需安装浏览器插件等优点,并且能够实时同步服务器端的任务处理进度。