`

Twitter框架学习二Http长连接技术实现server端push功能-Comet的理论与实战

阅读更多

Comet简介

在学习Twitter的架构中,发现他们广泛使用了Comet技术,基于Http长连接的服务器Push技术,Twitter本身对于数据的实时性要求较高,因此,采用Comet技术可以很好地解决他们的问题。

 

Comet 是一种新的 Web 应用架构。基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程序推送数据,而不需要客户端显式的发出请求。Comet 架构非常适合事件驱动的 Web 应用,以及对交互性和实时性要求很强的应用,如股票交易行情分析、聊天室和 Web 版在线游戏等。

 

3.基于Comet技术的开源项目Pushlet

 

下面是笔者翻译的关于Pushlet项目的白皮书的内容,原文出自:http://www.pushlets.com/doc/whitepaper-all.html

 

3.1 Pushlet 白皮书

 

PushLets是基于Servlet的Server端直接push数据到浏览器端的技术,这种push技术的实现不使用任何插件(Flash)或者Java Applet。它允许server端直接update web网页。

 

实现server端push功能通常采用Applet,Flash等技术。这些技术比较复杂也难于实现,有防火墙限制,而且需要另外的server的开发工作和维护。

 

Pushlets是基于Servlet的,数据是server端直接push到浏览器端的网页上,这就允许server可以实时地更新网页的内容。浏览器客户端采用JavaScript或者动态HTML技术,可以支持四种以上的浏览器,如NS(NetScape)和IE。这种机制是使用一个servlet的HTTP连接,这个连接会拿回一段JS代码给浏览器,浏览器然后执行这段代码,从而实现了网页端的数据实时更新。通过一个通用的Servlet(Pushlet),浏览器客户端可以订阅那些需要收到事件的主题。无论何时,server 推送一个事件,那些订阅了相关的主题的客户端都会被通知到。事件对象(Event Object)可以以JavaScript(DHTML clients),序列化的Java对象(JSON)或者XML形式返回。

 

3.2 Pushlet项目的初衷

 

这种机制从某种意义上来说是轻量级的,它利用了server的server的连接管理器和线程设备,javax.servlet APIs和标准的Java特性:如通过wait()和notify()机制实现的生产消费模型。

 

也有另外一种程序,需要订阅从server端不断更新的动态内容。如股票的feeds,系统的状态,天气预报和其它的监控程序。这些都遵从观察者模式(发布、订阅模式),由客户端注册订阅server的主题。

 

当页面装载后,我们应该如何通知浏览器端?或者我们应该怎么做,如果我们要实现选择性的部分更新,例如股票系统,通常只需要更新一个item就可以了?

 

3.Server端通知浏览器客户端的可行性方案

 

先让我们假定我们有一个Java的web server,我们要讲server端的数据通知客户端,达到这个功能有三种方式:

 

1)polling

最简单的方案是页面定时刷新,在HTML的Meta标签里加入定时刷新定义,网页每隔指定的时间都会重新刷新页面。

 

2)Server端的Callback

 

3)Messaging(MOM)

这个方案是,applet作为client端通过TCP/IP或者无连接的UDP消息连接,与消息中间件进行交互。你可能使用一个消息中间件产品如IBus,MQSeries(IBM)或者WebLogic Events(BEA)或者开发你自己的自定义消息。

 

4) 讨论

上面的每种解决方案在复杂性,安全,性能,扩展性,浏览器Java的兼容性和限制如防火墙的限制几个方面都有自己的各自的优缺点。哪种是最优化的方案在很大程度上依赖于你的应用程序的需求。例如,当用户需要一个直接的状态交互,例如白板程序,server端callbacks或者Message技术非常适用于这种场景。

 

除了上面的解决方案,我开发了一种技术-轻量级,瘦客户端,不需要applet或者任何插件,直接和脚本和HTML整合,使用标准的HTTP连接可以部署(从理论上)在支持Servlet的server上。当然我这个技术方案不是要取代上面的方案。我的意图是给你增加一种新的选择。做Java架构师或者开发人员,你应该权衡并选择哪种方案才是最适合你的应用程序。


4.Pushlet基础

什么是Pushlet,他们是如何工作的?从原理来看,Pushlets是异常简单的。下面我将展示这些基础知识,同时也会附带一些代码:


1).HTTP流
Pushlets基于HTTP流,它是一种这样的技术:它经常应用在多媒体的浏览上,例如QuickTime。当新的数据Push到client之后,连接保持开启状态,而不是关闭状态。

 

2).Example 1
基于HTTP流的基本理论,我们可以构造一个JSP文件,它定期不断发送新的HTML内容给Client端。

<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
</HEAD>
<BODY BGCOLOR="blue" TEXT="white">
<% 
  int i = 1;
    
  try {
    while (true) {
       out.print("<h1>"+(i++)+"</h1>");
       out.flush();
      
       try {
            Thread.sleep(3000);
       } catch (InterruptedException e) {
       out.print("<h1>"+e+"</h1>");
        }
     }
   } catch (Exception e) {
       out.print("<h1>"+e+"</h1>");
   }
%>
</BODY>
</HTML>

 

在实例页面上点击实例1。这个实例不是很有用,因为pushed的内容需要不断是添加到page上,而我们更加喜欢刷新它。

 

3)Example 2

 

这里我们直接跳到Pushlet的工作原理上。在实例页面点击example 2,可以看到这个页面是每3秒刷新一次的,到这里我们已经完成了工作了吗?

这个实例包含了三个文件: push-js-stream.html, push-js-stream-pusher.jsp 和 push-js-stream-display.html。

push-js-stream.html 是主页面,在HTML FRAME里面包含其它两个页面,让我们跟随事件的路线慢慢看下去。

下面这个文件列举了push-js-stream-pusher.jsp的内容,这个JSP文件是当请求它时,在server上执行的,这个JSP的主体部分代码如下:

7: <% 
  8:   /** Start a line of JavaScript with a function call to parent frame. */
  9:   String jsFunPre = "<script language=JavaScript >parent.push('";
 10:   
 11:   /** End the line of JavaScript */
 12:   String jsFunPost = "')</script> ";
 13:   
 14:   int i = 1;
 15:   try {
 16:   
 17:     // Every three seconds a line of JavaScript is pushed to the client
 18:     while (true) {
 19:     
 20:        // Push a line of JavaScript to the client 
 21:        out.print(jsFunPre+"Page "+(i++)+jsFunPost);
 22:        out.flush();
 23:        
 24:        // Sleep three secs
 25:        try {
 26:             Thread.sleep(3000);
 27:        } catch (InterruptedException e) {
 28:             // Let client display exception 
 29:             out.print(jsFunPre+"InterruptedException: "+e+jsFunPost);
 30:        }
 31:      }
 32:    } catch (Exception e) {
 33:             // Let client display exception 
 34:             out.print(jsFunPre+"Exception: "+e+jsFunPost);
 35:    }
 36: %> 


这里我们又看到了一个定时循环:每3秒钟向浏览器打印了一些HTML代码。但是请注意一点,这个不是push 
HTML,而是JavaScript,这是什么意思?

它push了一行像这样的一行代码:<script language=JavaScript >parent.push('Page 
4')</script>,这对于浏览器是什么意思呢?浏览器有它自己运行的JavaScript引擎,
它会执行每次来的新的JS代码。它是调用parent.push()的JavaScript代码。当前的parent是Frame的Parent,它是我
们刚来list的第一个文件push-js-stream.html,我们再看看这里有什么:
<script LANGUAGE="JavaScript"> var pageStart="<HTML><HEAD></HEAD><BODY BGCOLOR=blue TEXT=white><H2>Server pushes: <para>"; var pageEnd="</H2></BODY></HTML>"; // Callback function with message from server. // This function is called from within the hidden JSP pushlet frame function push(content) { // Refresh the display frame with the content received window.frames['displayFrame'].document.writeln(pageStart+content+pageEnd); window.frames['displayFrame'].document.close(); } </script> </HEAD> <FRAMESET BORDER=0 COLS="*,0"> <!-- frame to display the content pushed by the pushlet --> <FRAME SRC="push-js-stream-display.html" NAME="displayFrame" BORDER=0 SCROLLING=no> <!-- Hidden frame with the pushlet that pushes lines of JavaScript--> <FRAME SRC="push-js-stream-pusher.jsp" NAME="pushletFrame" BORDER=0 SCROLLING=no> </FRAMESET>

上面的代码我们可以看到服务端Push过来的Javascript push()方法在哪里得到执行了。

 

这就是Pushlets的基本的原理:我们只是从一个Servlet stream 若干行JS。这些JS被浏览器解释执行。这个例子说明了Pushlet的工作机制,但是仍然有几个问题需要解决。并且需要添加更多的feature。从这个原因来讲,我已经build了一个轻量级的server端的Pushlet框架(如下面的类视图所示),加上几个客户端的JS类库。

 

5.不只是Java-动态HTML
DHTML指的是HTML,CSS,JavaScript和浏览器DOM的融合。传统意义上来讲,只有通过从server重新装载page才能改变page的内容,DHTML允许page装载后仍然能够完全控制一个HTML文档,你也许已经看到了一些web上的实例如image的滚动,弹出内容和折叠菜单。DHTML可以支持4种类型的浏览器。

从程序员角度看,浏览器的dom,例如它的frame,段落,表等等都代表了一种层次性的对象模型-DOM。DHTML允许页面已经装载后能够完全控制一个HTML文档。通过JS,你可以操作DOM,因此你也可以改变document的内容和外观。你可以从这些元素抓取用户事件,如鼠标move,form的提交。例如鼠标滑过一个图片会产生一个mouse-over事件。document元素甚至可以达到动画效果,这看起来很不错,是吧,我们只是需要熟悉DHTML的标准,但是谁定义了DHTML的标准?

 

6.框架的设计
Pushlet框架允许client从server订阅主题,client会相继收到事件。这个框架的基本设计模式是发布-订阅模式,也称作观察者模式,它既有server,又有client的组件。

  • 围绕Pushlet类而设计了server端的集合
  • 在DHTML客户端为了接收事件而设计了可以重用的客户端的JS类库(pushlet.js)
  • 为Java客户端接收事件而设计客户端的Java类(JavaPushletClient.java and JavaPushletClientListener.java)
  • 为显示DHTML层而设计的跨浏览器的DHTML工具库(layer.js, layer-grid.js, layer-region.js)

1). Server-side 类设计图(下面的图只适用于0.04版本)


 

 

 

 

 

  • 大小: 9.5 KB
分享到:
评论
2 楼 cuisuqiang 2012-10-10  
menuhin 写道
哇,好文章,正需要这方面的资料呢!

http://cuisuqiang.iteye.com/blog/1693775
1 楼 menuhin 2010-05-10  
哇,好文章,正需要这方面的资料呢!

相关推荐

    catalina-comet.jar

    8. ** 集成其他框架**:Comet技术可以与其他Web开发框架(如Spring、Struts等)结合,以实现更复杂的业务逻辑。Catalina-Comet.jar的兼容性使得开发者能够轻松地在现有的应用架构中集成Comet功能。 在实际开发中,...

    CSharp HTTP长连接(Comet)

    在IT行业中,HTTP长连接(也称为Comet技术)是一种用于实现服务器向客户端实时推送数据的方法,常用于构建实时交互的应用,如聊天室、股票报价、在线游戏等。C#作为.NET框架的主要编程语言,提供了丰富的工具和技术...

    java-comet

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

    CometAsync_net:C#实现基于http长连接“服务器推”-Comet技术

    C#实现基于http长连接“服务器推”-Comet技术 很多应用譬如监控、即时通信、即时报价系统都需要将后台发生的变化实时传送到客户端而无须客户端不停地刷新、发送请求。 本项目基于 AJAX 的长轮询方式实现。 ...

    gwt-comet-jar包+实例+source.jar包,

    里面东西很多,都是关于GWT-COMET的内容,实现gwt的服务器推技术,包括gwt-comet-examples-1.2.3:google官网上的Test实例;gwt-comet-1.2.3.jar:jar包,gwt-example:聊天实例源代码(.java的),gwt-event-source...

    服务端推技术 - Server-side Push 多示例

    在"服务端推技术 - Server-side Push 多示例"中,我们可以深入探讨几种实现Server-side Push的技术和策略: 1. **Comet技术**:Comet是一种利用HTTP持久连接来实现双向通信的技术,它可以让服务器在连接保持打开的...

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

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

    atmosphere-applet-comet.jar.zip

    1. **Atmosphere框架**:Atmosphere是一款开源的Java库,旨在解决在Web浏览器与服务器之间进行长连接通信的问题。它支持WebSocket、Server-Sent Events(SSE)等多种实时通信协议,同时兼容各种Web容器,如Tomcat、...

    Comet(Http长连接)

    综上所述,Comet技术通过HTTP长连接实现了服务器向客户端的实时数据推送,显著改善了Web应用的交互体验。PHP和JavaScript结合,可以轻松构建出这样的实时应用实例。然而,Comet也存在一定的缺点,如服务器资源消耗较...

    Comet:基于 HTTP 长连接的“服务器推”技术 (实例)

    2. **后端服务器**:可能使用PHP、Java、Python或其他服务器端语言,实现Comet服务器端逻辑,保持与客户端的长连接,并处理消息的接收和发送。 3. **数据存储**:存储用户聊天记录,可能使用关系型数据库如MySQL或...

    Comet, 下一代反向AJAX(即服务器推送技术- Server-side push)

    Comet 有时也称反向 Ajax 或服务器端推技术(server-side push)。其思想很简单:将数据直接从服务器推到浏览器,而不必等到浏览器请求数据。听起来简单,但是如果熟悉 Web 应用程序,尤其是 HTTP 协议,那么您就会...

    卓越信通TSC-Comet系列以太网交换机样本.zip

    卓越信通TSC-Comet系列以太网交换机是一款专为满足企业网络需求而设计的高性能、高可靠性的网络设备。此系列交换机在现代网络架构中扮演着至关重要的角色,提供稳定、快速的数据传输服务。下面我们将深入探讨TSC-...

    web聊天 serverpush servlet实现

    本篇将主要讨论使用Servlet实现的Server Push技术,即服务器端主动向客户端推送数据。 【描述】: 这篇博客(原文链接:https://zw7534313.iteye.com/blog/703114)详细介绍了如何利用Servlet实现一个简单的Web...

    comet框架例子项目

    常见的Comet实现技术包括HTTP流、HTTP长轮询和WebSocket等。 在这个项目中,`testcomet`很可能是项目的主目录,包含了所有相关的源代码、配置文件以及可能的测试案例。以下是一些可能包含在项目中的关键组件和知识...

    Python库 | unbabel-comet-0.0.1.tar.gz

    在本文中,我们将深入探讨名为"unbabel-comet-0.0.1"的Python库,该库被封装在一个名为"unbabel-comet-0.0.1.tar.gz"的压缩文件中。 "unbabel-comet-0.0.1.tar.gz"是一个典型的源代码打包文件,它采用了tar格式用于...

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

    Comet4j是一种基于Java的实时通信框架,它利用了HTTP长连接技术,实现了服务器向客户端的高效、低延迟的消息推送。在这个压缩包中,包含了Comet4j框架运行所必需的一些关键组件。 首先,`comet4j.js`是Comet4j的...

    基于Bayeux协议的Comet框架的研究与实现.pdf

    "基于Bayeux协议的Comet框架的研究与实现"这一标题表明了本文的核心内容,主要探讨的是如何运用Bayeux协议来构建一个Comet框架。Bayeux协议是一种专为实时Web应用设计的双向通信协议,而Comet则是一种使服务器能够向...

    server push

    不过,对于Server Push,我们不会直接调用这个方法,而是让DWR保持一个长连接,等待服务器推送数据。 4. **建立Push通道**: 使用DWR的`Push` API,客户端可以建立一个Push通道,注册一个回调函数来处理服务器推送的...

    http长轮询技术comet的实现

    通过comet实现了一个聊天功能。 1.需要在tomcat的server.xml里面配置 &lt;Connector port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" /&gt; 2.需要...

    Comet:基于_HTTP_长连接的“服务器推”技术

    Comet技术的核心是使用HTTP长连接,即客户端与服务器之间维持一个持久的连接状态,服务器可以随时通过这个连接将数据推送给客户端。相较于传统短连接,长连接可以显著减少每次数据交换所需的开销,提高效率。 #####...

Global site tag (gtag.js) - Google Analytics