服务器推送技术

来源:互联网 发布:sql count 1 用法 编辑:程序博客网 时间:2024/04/28 13:38

3.1服务器推送技术(Server Push)

3.1.1服务器推送技术概述

服务器推送技术是最近Web技术中最热门的一个流行术语,它是继AJAX之后又一个倍受追捧的Web技术。我们可以认为AJAX解决了单用户响应的问题,而服务器推送则解决了在保证性能的前提下进行协同多用户的响应问题。由图3.1和图3.2的比较可以看出,服务器推送的优点在于它可以在任何时候向客户端发送数据,而不仅仅只是响应用户的输入请求。而发送数据是在一个已有的单连接上进行的,因此可以大大降低发送数据的延迟时间(建立连接的开销,以及客户端发送请求的等待时间)。

传统模式的Web系统以客户端发出请求、服务器端响应的方式工作。浏览器的主要工作是发送请求、解析服务器的回复消息并显示。服务器的主要工作是根据接收浏览器发送的各种请求作出响应。

浏览器作为Web应用的前台,自身的处理功能比较有限。AJAX是浏览器技术发展的成果,通过在浏览器端发送异步请求,提高了单用户操作的响应性。AJAX将整个页面的刷新变成页面局部的刷新,并且数据的传送是以异步方式进行,这使得网络延迟带来的视觉差异将会消失。AJAX还利用DHTML和丰富的JavasSript语言来模拟桌面系统的各种事件和响应过程,以及平滑滚动和拖拽的效果。在AJAX的世界中,除了传统的CAD设计软件和大型游戏软件等因为对系统硬件的苛刻需求,还离不开桌面系统以外,似乎其他所有的应用都可以变成Web应用了。

但是传统的Web应用包括基于AJAX的Web应用还是存在一个致命的缺陷,使得Web系统无法满足传统桌面系统的需求,那就是:服务器发起的消息传递(Server-InitiatedMessage Delivery)。在很多的应用当中,服务器端需要向客户端主动发送消息或信息。因为服务器掌握着系统的主要资源,能够最先获得系统的状态变化和事件的发生。当这些变化发生的时候,服务器需要主动地向客户端实时地发送消息。例如监控、即时通信、即时报价系统等都需要将后台发生的变化实时传送到客户端而无须客户端不停地刷新页面、发送请求。在传统的桌面系统中,这种需求没有任何问题,因为客户端和服务器之间通常存在着持久的连接,这个连接可以双向传递各种数据。而基于I-1TrP协议的传统Web应用却不行,在这些系统中,Web服务器总是被动地根据客户端的请求发送数据,它无法保证服务器将更新的信息实时地传送给客户端,从而用户可能在“过时”的信息下进行操作。

在传统的Web系统中,只有当浏览器向服务器发送出请求后,服务器才会发送出数据。而浏览器其实并不知道服务器的信息什么时候会有改变,为了模拟实时的交流,或者不想错过某些信息,只能通过轮询(Polling)技术不断刷新页面来获得最新的数据(见图3.3)。这种方式不但浪费服务器的资源,最重要的是每次建立或关闭新的Hr】『P连接都有一定的延迟,这种延迟使得频繁信息传递的应用无法忍受。于是就产生了“服务器推送技术刀。

服务器推送技术的基础思想是将浏览器主动查询信息改为服务器主动发送信息。服务器发送一批数据,浏览器显示这些数据,同时保证与服务器的连接。当服务器需要再次发送一批数据时,浏览器显示数据并保持连接。以后,服务器仍然可以发送批量数据,浏览器继续显示数据,依次类推。这种技术可以被应用在股票实时情报,系统状态报告,天气情况等监测系统中。使用服务器推送技术后的系统模型如下图所示:

3.1.2服务器推送技术的实现方案

服务器推送技术在很久以前就出现过,例如Netscape曾经推出适用于Push技术的专用浏览器和经过修改的HTML语言。但是这仅仅在特定的浏览器中才能使用,其他流行的浏览器(Ⅲ等)就不兼容这种技术。以前实现服务器推送的方案主要是在浏览器端安装插件,基于套接口传送信息,自定义TCP/IP信息的Applet来实现,或是使用RMI、CORBA进行服务器端的远程调用。这些技术往往由于复杂而产生诸多不利之处:技术难以实现、存在防火墙限制(因为需要打开非HTTP的通讯端口)、需要额外的Server开发和维护。并且除了刷新整个页面或者完全采用Applet展示内容之外,很难找到别的方法将客户端Applet的状态和浏览器的页面内容集成在一起。

现在的服务器推送技术是基于HTTP长连接而实现的。它保持原有的H兀P协议不变,在服务器端改变处理方式,使得服务器能够使用浏览器已经打开的册连接,主动向浏览器发送消息。这里关键的技术是要保持原有的HITP连接不断,一旦拥有持久的连接,服务器就可以根据自己的数据更新,随时地向客

户端发送最新的信息。

Alex Russell(Dojo Toolkit的项目领导人)称这种基于哪长连接、无须在浏览器端安装插件的服务器推送技术为Comet。目前已经出现了一些成熟的Comet应用以及各种开源框架。一些Web服务器如Jetty也在为支持大量并发的长连接进行了很多改进。根据客户端处理长连接技术的不同,常用的有两种Comet应用的实现模型。

3.1.2.1基于AJAX的长轮询(10ng-polling)方式

如图3.4所示,AJAX的出现使得JavaScfipt可以调用XMLHttpRequest对象发出的肌’P请求,JavaScript响应处理函数根据服务器返回的信息对HTML页面的显示进行更新。使用AJAX实现服务器推送与传统的AJAX应用不同之处在于:

1.服务器端会阻塞请求直到有数据传递或超时才返回。

2.客户端JavaScript响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。

3.当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。基于长轮询的服务器推模型一些应用及示例如“Meebo”,“Pushlet Chat”都采用了这种长轮询的方式。相对于上面提到的“轮询”(polling),这种长轮询方式也可以称为“拉”(pull)。因为这种方案基于AJAX,具有以下一些优点:请求异步发出;无须安装插件;IE、FireFox都支持AJAX。

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

目前Ⅲ不支持基于Streaming AJAX。

3.1.2.2基于iframe及htmlfile的流(streaming)方式

iframe是很早就存在的一种HTML标记, 通过在HTML页面里嵌入一个隐葳帧,然后将这个隐葳帧的SRC属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。上面提到的AJAX方案是在JavaScript里处理XMLHttpRequest从服务器取回的数据,然后Javascript可以很方便的去控制HTML页面的显示。同样的思路用在iframe方案的客户端,iframe服务器端并不返回直接显示在页面的数据,而是返回对客户端Javascript函数的调用,如:<script type=”text/javascript”>js_func(”data from server”)</script>。服务器端将返回的数据作为客户端JavaScript函数的参数传递;客户端浏览器的Javascript引擎在收到服务器返回的JavaScript调用时就会去执行代码。简而言之,其基本原理就是从Servlet把JavaScript代码作为H兀P流推送到浏览器。这些代码被浏览器的JavaScript引擎解释并完成相应的工作,于是便完成了从服务器端的Java到浏览器中的JavaScript的回调。

从图3.5可以看到,每次数据传送不会关闭连接,连接只会在通信出现错误时,或是连接重建时关闭(一些防火墙常被设置为丢弃过长的连接,服务器端可以设置一个超时时间,超时后通知客户端重新建立连接,并关闭原来的连接)。

使用iframe请求一个长连接会有一个不足之处:IE、Morzilla Firefox下端的进度栏都会显示加载没有完成,而且Ⅲ上方的图标会不停的转动,表示加载正在进行。一个被称为“htmlfile”的ActiveX解决了在正中的加载显示问题,gmail+gtalk产品中使用了这个解决方案。

3.2开源的服务器推送一Pushlets ·

3.2.1 Pushlets概述

Pushlets是一个开源的Comet框架,在Servlet机制下,数据从服务器端的Java对象直接推送(push)到动态HTML页面,而无需任何JavaApplet或者插件的帮助。它使服务器端可以主动地更新客户端的web页面。浏览器为兼容JavaScriptl.4版本以上的浏览器(如Intemet Explorer、FireFox),并使用JavaScript/DynamicHTML特性【5】。Pushlets支持上一小节提到的两种服务器推送的实现方式,既提供了基于AJAX的JavaScript库文件用于实现长轮询方式的服务器推送,也提供了基于iframe的JavaScript库文件用于实现流方式的服务器推。原则上,Pushlets框架能够运行在任何支持Servlet的服务器上、防火墙的后面。‘Pushlets通过标准Java特性中Object的wait()和notify()实现了观察者模型:客户端发送请求,订阅感兴趣的事件;服务器端为每个客户端分配一个会话ID作为标记,事件源会把新产生的事件以多播的方式发送到订阅者的事件队列里。浏览器只需要发送两个请求,一个是连接请求事件,一个是对后台事件进行监听订阅的请求,如果后台对应的数据发生了变化,则这个变化会反应到订阅者的事件队列中,这种机制是轻量级的。

3.2.2 Pushlets架构

Pushlets框架允许客户端订阅在服务器端的主题(subject),而服务器则接收订阅,然后在服务器端的订阅主题所对应的数据变化时推送数据到客户端。此框架的基本设计模式是发布/订阅(Publish/Subscribe),也被称为观察者模式(Observer)。它由Server和Client两部分组建而成。

3.2.2.1 Server端架构

Server端由围绕着Pushlet类的Java类集合构成。下面的UML图表示了几个最重要的类之间的关系,包括Publisher、Subscriber和Event。客户端通过HTTP请求连接到Pushlet servlet,订阅并接收消息。请求中包含了要求订阅的主题和接收消息的方式(JavaScript调用、XML或者Java序列化对象,默认为JavaScript调用)。Publisher对象中记录了它的所有Subscriber,可以将Event发送到相应的Subsciber中。

对照图3.6,简要说明一下几个关键的类:Pushlet是一个Servlet,接收来自客户端的请求,并创建一个订阅者(Pushlet Subscriber),然后调用初始化方法订阅一个主题,最后由该订阅者保持客户请求,返回内容。

PushletSubscriber是与每个客户端对应的订阅者,首先根据客户端的请求建立客户端适配器ClientAdapter,并将自己注册到一个特定的Pub lisher那里,然后保持这个http连接,并将其自身阻塞于一个事件队列之上,事件则对应于一个主题:如果有事件入队列,则被唤醒,并调用ClientAdapter向客户端推送数据:

C1ientAdapter:屏蔽了不同的客户端协议的差异,将从PushletSubscriber获取到的事件转换为JavaScript格式并将它推送到客户端浏览器:

Publisher:采用单实例模式,提供静态接口供其他类订阅/发布消息,它维护着一组订阅者的列表:事件到来时,通过比较订阅者的主题和事件的主题,可将事件放入相应的事件队列,唤醒所有在此事件队列上等待的客户端订阅者(PushletSubscriber):

Postlet:类似于Pushlet,其所处位置和Pushlet相同,用于客户端主动服务器端发送消息。

Eventer source:事件源,通过监听外部事件而产生Pushlet事件,并调用Publisher发布事件。

3.2.2.2 Client端架构

Client端由脚本与页面组成。如果选择使用基于iframe的服务器推送方式,有可重用的JavaScript库(pushlet.js)和用来在DHTML client(这里指浏览器)中接收事件的HTML(pushlet.html)。pushlet.html实现了一个隐藏的iframe来接收来自server的消息,它的父页面要实现一个名为push()的方法做为来自服务器端的JavaScript回调。在pushlet.js中实现了这个方法,可以为所有的浏览器客户端所重用。如果选择使用基于AJAX长轮询的方式,则有可重用的JavaScript库(ajax—pushlet.is)。不管使用哪种方式,只需在客户端实现一个onData()的JavaScript函数就能实现个性化的操作,处理服务器推送过来的数据。

Client端Java类:JavaPushletClient和JavaPushletClientListener,负责在Java client中接收事件。

.2.3 Pushlets优点

与基于CORBA/RMI的Java applet解决方案相比,Pushlets具有以下一些优点。

1.直接与浏览器中的DHTML集成:服务器产生的数据可以立即发送到浏览器的页面内容中。HTML的所有布局均可应用。

2.标准的HTTP端口和协议:消息和蹦I/CORBA使用非标准端口(相对HTTP标准端口而言),遇到“防火墙”、“禁止回调’’、“禁止接收UDP数据”的浏览器安全限制时可能无法工作。

3.客户端负载:基于CoRBA/蹦I的Java applet使客户端在启动时更加沉重,并消耗更多的资源。

4.无需额外的server:消息和跚I/CORBA需要单独的server产品。Pushlets理论上可以在任何server引擎上运行,并具备连接管理和多线程能力。

3.3 F Monitor项目中的服务器推送

下面将以F Monitor系统为例,具体说明如何在一个Web系统中实现服务器推送。

3.3.1 F Monitor中服务器推送的设计

服务器推送主要由三个部分组成:消息、消息的发送方、消息的接受方。

F Monitor系统中的服务器推送依赖于开源项目Pushlets来实现。在Pushlets的框架中,服务器推送的消息是一个名为Event的Java类对象,该对象包含了一个Map来包含消息中的具体内容,以及一个String类型的Topic来表示消息的主题,只有订阅了该主题的消息接受者才会收到该消息,类似于JMS的Topic。在F Monitor中,不同的事件通过不同的主题发送给客户端,事件的Topic命名采用层次化的树命名结构。比如:“/Monitor/ssb/finishEvent”这个topic就表示名为ssb这个卖方机构下的finishEvent类型的事件,只要订阅了“/Monitor/ssb”这个topic,客户端就可以收到其下属的所有类型的事件消息,如果订阅了“/”则表示订阅所有Topic的消息。

其次需要设计消息的发送者,Pushlets支持三种不同类型的消息发送方式:直接发送消息、使用事件源发送消息、使用Pushlets的协议发送消息。直接发送方式只要调用Dispatcher.getInstance 0.multicast 0,Dispatcher.getlnstance().unicast()或Dispatcher.getInstance().broadcast()等方法就可以将构建好的消息以广播、多播或者单播的方式发送出去。使用事件源发送消息的方法,则需要实现一个继承于EventSource的Java类,通过在配置文件中声明的方式由Pushlets框架来统一管理事件源,这种发送方式比较适用于需要定时发送事件的发送源。使用Pushlets协议发送消息则提供了一种可以在Pushlets线程之外使用Pushlets协议发送消息的方式,系统可以在任何Java应用中实现服务器推送。在F Monitor系统中,直接发送是比较合适的方式,因为我们的事件来源于所监测的系统F,F Monitor随时可能需要推送事件给浏览器,因此事件的发送是随时的,而不是定时的,因此直接发送的方式比使用事件源定时发送的方式更适合于F Monitor的系统。

有了消息的发送者,接下来需要设计消息的接收者。接收者需要申明其接受消息的格式(JavaScript、XML、Java序列化对象三种格式)和其订阅的消息Topic。在我们的F Monitor系统中,将使用基于AJAX的浏览器客户端作为接受者。Pushlets提供了一些可重用的JavaScript文件支持DHTML和AJAX的客户端(主要是ajax—pushlet.js,pushlet.js和pushlet.html)。ajax—pushlet.js提供了浏览器端的JavaScript库实现基于AJAX的服务器推送。只需将这些文件集成到我们的系统中,就能很方便的实现服务器推送的接收方。

3.3.2 F Monitor中服务器推送的具体实现

3.3.2.1系统消息的实现

在F Monitor中,服务器推送的事件都是Event对象,不同的事件具有不同的Topic和Map属性。需要说明的是Topic的结构设计,如上-d,节所说,Topic是个树状的结构,F Monitor中将Topic的结构划分为机构名称、消息类型、货币对三个层次,具体结构如图3.7所示。一个典型的Topic是这样:/Monitor/SSB/FinishEvent/USD/ARS。

3.3.2.2消息发送方(服务器端)的实现

将pushlet.jar文件置于F Monitor项目的web文件夹下,同时在web.xml文件中声明pushlet的servlet。

消息的发送方,在服务器端,实现以下代码,只需在需要推送消息的时候调用该代码,就能将消息发送到指定的Topic上。

3.3.2.3消息接收方(浏览器端)的实现

在html文件中引入pushlets提供的客户端支持文件:ajax-pushier.js。

3.4本章小结

在本章中,介绍了服务器推送技术的概念和原理,及其两种比较常见的实现方案。并且从实际应用角度出发,研究它适合何种项目,以及会带来的好处。另外,还介绍了一个开源的服务器推送框架Pushlets,包括它的架构和特点,因为在F Montior中将使用这个开源项目。最后,详细介绍了F Monitor项目中如何

使用Pushlets实现服务器推送,包括其设计与具体实现。通过本章的介绍,我们对服务器推送的技术以及其在实际项目中的应用有了比较清晰的认识。


转载于:http://www.cnblogs.com/my6521/archive/2011/01/27/1946230.html