反向Ajax.doc_第1页
反向Ajax.doc_第2页
反向Ajax.doc_第3页
反向Ajax.doc_第4页
反向Ajax.doc_第5页
免费预览已结束,剩余4页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

3.4 反向Ajax 2009-01-14 16:05 龚波 人民邮电出版社 我要评论(0) 摘要:DWR实战第3章DWR高级主题,本章中将进一步深入了解、学习DWR所提供的高级主题,还将讨论安全性、错误处理、访问其他URL、反向Ajax、与其他框架集成,以及DWR中的Java 5注解支持。本节为大家介绍的是反向Ajax。 标签:DWRAjaxDWR实战 Oracle帮您准确洞察各个物流环节3.4 反向Ajax当开始对Ajax感兴趣时,Ajax始终在变化着,比如出现了反向Ajax。图3-6以图形方式展示反向Ajax的工作原理。(图形有点类似于发出的炮弹在讨论反向Ajax之后,我们会进一步细化这个图形的讲解。)(点击查看大图)图3-6 用图形展示DWR中的反向Ajax(经DWR创建者Joe Walker授权使用)反向Ajax是比较新的内容,在过去数月内引起广泛重视。反向Ajax的基本概念是,客户端不必从服务器获取信息,服务器会把相关信息直接推送到客户端。这样做的目的是解决Ajax传统Web模型所带来的一个限制:实时信息很难从技术上解决。原因是,客户端必须联系服务器,主动询问是否存在变更,如果有变更就会更新页面(或者页面的一部分)。虽然可以非常快速完成这个操作,让人感觉好像是实时的,但是实际上不是实时的。我们需要的是,服务器联系查看其页面的所有浏览器,并通告所发生的变更。反向Ajax是克服这个限制的一种方式。像Ajax本身一样,这不是一门专门的技术,而是按照不寻常方式组合使用已有的技术达到不寻常的效果。我们都知道,传统的Web模式(也就是非Ajax的应用程序)有一系列鲜明的事件。简单来说,用户在客户端的一个动作会导致向服务器发出一个请求,然后服务器按照请求进行相应处理,并把处理结果作为响应传回客户端,这个响应通常是一个完整的新的UI视图。这种处理过程反复循环,直到用户决定离开当前Web站点。图3-7以图形化方式展示处理过程的事件序列。(点击查看大图)图3-7 传统Web模式的基本事件处理序列基于Ajax的应用程序的事件序列稍微有差别,如图3-8所示。在图3-8中,某个用户动作会导致对某个客户端Ajax引擎的调用,不论它是JavaScript代码,还是其他库。这个引擎会向服务器发出一个请求,服务器按照非Ajax模式进行处理,然后返回响应。响应内容首先被Ajax引擎处理,然后调用某些客户端代码以更新页面。同样,这个循环会无止境进行,直到用户离开当前页面。反向Ajax表示另外一种事件序列,但是是基于图3-8的Ajax模式,其中有一个双向的信息流,即通常的客户端发起的信息流和新的服务器发起的信息流(接下来会使用图表更详细地说明)。现在,有一个事实:反向Ajax实际上是个幻觉!但是,这是一个故意为之的幻觉,而不是无意义的幻觉。在当前HTTP技术的限制下,根本找不到真正把信息从服务器推送到客户端的方式,因为这个协议是无状态的,并且客户端发起的连接一旦断开,服务器就不可能了解客户端。不管到底哪一方发起这个连接,都不存在从客户端到服务器的持续连接。虽然没有真正的推送技术,但是可以完美地模拟它!现在总共有三种DWR支持的技术可以辅助完成这种技术,其中两种技术都属于主动的反向Ajax,第三种被认为是被动的反向Ajax。下面逐个讨论每种技术以及DWR提供的支持。(点击查看大图)图3-8 Ajax中基本的事件序列3.4.1 轮询严格地说,轮询技术并不是专用于Ajax的,它已经存在很长时间了。这是服务器推送的最简单形式,即使不熟悉这个术语,也可能已经知道这个术语的含义了。假设有个老式的Web页面,没有使用Ajax或者其他特殊的技术。假定使用刷新标签,每隔数秒就更新这个页面。这就是所说的轮询!客户端定时轮询服务器,看是否存在更新,并且显示新信息(更准确地说,仅仅显示服务器传回的当前信息。相对于在最新轮询事件之前所看到的信息,服务器传回的当前信息也许是新内容,也许不是。但是,从表面看来,页面中有的部分被新信息替换,而没有变化的地方仍旧保持不变)。在网页上,使用一些简单的JavaScript代码以持续地更新页面,就可以实现相同的事情。确实,能够从表面实现所谓的推送,这就是轮询技术。在Ajax中,事件流会更加复杂,但是实质上是一样的,如图3-9所示。(点击查看大图)图3-9 轮询技术的事件顺序在该图中,可以看到前三个轮询事件发生了,但是没有任何用户交互。客户端或者Ajax引擎发起这个请求,独立于用户所做的任何事情。同时,请注意,当接收到响应时,前三个轮询事件并没有向浏览器UI发出调用。这意味着,页面不需要任何更新,因为没有提供任何新数据。这就是两种主动式反向Ajax方法的一种,因为有一种自动化动作能够从服务器端获取更新,传送给客户端。另一种主动式方法被称为Comet。3.4.2 Comet第二种主动式反向Ajax方法是Comet,之所以使用这个名称,是因为希望它能够像Ajax一样彻底解决问题。图3-10简单描述了Comet的基本原理。(点击查看大图)图3-10 Comet技术的事件顺序这个基本概念实际上非常简单:客户端向服务器发出一个请求,服务器开始响应。然后,服务器按照非常缓慢的频率持续响应。虽然很慢,但是连接仍旧处于活跃状态。思考一下,实际上,我们已经解决了一个HTTP限制,那就是客户端和服务器端没有静态连接。然后,数据双向进行传输,让你感觉到好像是服务器发起的实时更新。很多人根本不认为这种Comet技术是反向Ajax,这种说法也有一定的道理,但是Comet实际上是促使Ajax闻名于世的催化剂。Alex Russell最早提出术语Comet,他是非常流行的Dojo工具集()的最初设计者。我只想证明,DWR全面支持反向Ajax(包括Comet),它并不是Joe或者其他DWR参与者的发明(尽管大家认为他们做得最好)。如果曾经参与部分企业级项目的开发工作,也许有如下疑问:反向Ajax和Comet可以等同吗?它会伤害我的服务器吗?答案只能是也许吧。应该清楚,长时间保持连接活跃是服务器过载和用完请求处理进程的原因。有时形象地说成线程饿死应用程序服务器,这肯定是一件非常糟糕的事情!幸好DWR提供了解决办法。当处理活动模型时,DWR提供三种不同的反向Ajax模式(包括轮询、Comet和即将讨论的piggybacking,有时把这三种模式称为子模式)。第一个模式是全流(full-streaming)模式。这是反向Ajax默认使用的模式,通过每60秒左右关闭一次连接,确保浏览器处于活跃状态(这时候,会重新创建连接,以让用户感觉到连接是始终活跃的)。DWR也会实现服务器的简单优化方式,可以基于服务器负载,动态调整连接时间和超时时间。第二个模式是早期关闭(early closing)模式。在这种模式中,工作机制类似于全流模式,区别是如果没有传送给浏览器的输出,则连接仅仅保持60秒。一旦出现浏览器输出,DWR会在连接关闭之前,停止一段可配置的时间,强迫代理传输信息。也可以配置服务器第一次输出和连接关闭之间的时间延迟,在早期关闭模式下,延迟时间默认是60秒。早期关闭模式的缺点是,对于输出非常频繁的应用程序,会导致单击数量非常庞大。在输出频率非常低的应用程序中,一个事件可能导致所有已连接的浏览器会同时重新连接。在输出频率很低,但是连接了大量浏览器的情况下,通过切换到轮询模式,可以大幅度降低服务器的负载。如果在早期关闭模式中,把第一次输出和连接关闭之间的时间配置为默认的 1,或者其他大于1000(1秒)的值,DWR就会在IE中使用iFrame,以允许来自于服务器的信息流。这会导致熟悉的页面重新加载,所以如果准备使用早期关闭模式,可能希望在配置延迟时间时,不能使用默认值或者低于1000的值,这样可以避免单击问题。第三个模式实际上就是piggybacking,这个模式已经细分为很多不同的种类!3.4.3 piggybacking如图3-11所示,反向Ajax的最后一种方式是piggybacking方法。这种方法是DWR提供的一种被动式方法。之所以称为被动式,是因为启动它需要一个用户交互动作(从原理上来说不需要用户交互动作,但是实际上不行)。实际上,不管如何,piggybacking和被动式反向Ajax都是同义的,因为我认为,不存在被动式反向Ajax的其他形式。在这个模式中,用户会执行某种动作,这个动作会发出一个Ajax请求。服务器会做出合适的响应,但是除此之外,还会添加与所执行操作并不直接相关的内容。类似于与理发师的对话:好的,我准备为您洗头发了,还有,您的汽车需要更换汽油了。这也许是与理发师的临时性对话,但是在piggybacking反向Ajax中,内容当然是标准的和固定的!作为一种被动式技术,piggybacking模式的好处是,这样做不会给服务器带来其他的负载。服务器依旧等待来自于客户端的请求,但是差别是服务器会进行排队响应,并在客户端的下一个请求中进行发送。这是实现反向Ajax的一种灵活方式,但是不会给服务器增加负担(除非排队的事件很多导致内存被消耗完,但是这是其他层面的问题)。(点击查看大图)图3-11 piggybacking技术的事件顺序当没有特殊指明时,DWR会使用piggybacking,这是默认的设置,所以在默认情况下,启用反向Ajax时,不会导致服务器超载。那么,如何能够准确地启用反向Ajax,如何配置前面提到的各种选项,以及如何在代码中实现呢?本书在很多地方都说到,DWR的实现方式非常简单,下面会逐步涉及。3.4.4 反向Ajax的实现代码使用DWR实现反向Ajax的第一步是,使用一些新的配置元素(本书免费提供的源代码中有个reverseajax Web应用程序,其中包含所有配置元素和使用范例)。首先,在web.xml文件中,需要添加DWR servlet的一些新的初始化参数:实际上,只需要第一个参数,也就是activeReverseAjaxEnabled。其他两个参数是可选的(如果使用轮询技术,需要使用第二个参数ServerLoadMonitor)。同时,请注意与timeToNextPoll参数相关的注释。实际上,假设你使用一个名为disconnectedTime的参数,但是由于2.0.2版本之前的DWR存在一个错误,因此必须使用timeToNextPoll。要记住,如果升级DWR版本,没有正常使用参数,应用程序可能会失效。除了上述配置,为启用反向Ajax,页面上还需要一些JavaScript代码,其实也很简单,即dwr.engine.setActiveReverseAjax(true);。只需要上述代码和web.xml文件中的配置,就可以激活反向Ajax了。如果把反向Ajax添加到已有的DWR Web应用程序中并激活它,然后使用Firefox访问它,并查看Firebug控制台,就会注意到每秒都会发出一个新请求。看看,这就是轮询!另外一个需要关注的地方是如何真正处理这些轮询请求。通常是在服务器端编写一些代码,以更新附加到服务器端的每个客户端的会话。DWR会记录与之联系的每个客户端,分别存储每个客户端的会话。这一点与通常的HTTP会话不同。(如果HTTP会话实际上被DWR内部使用,我也不会奇怪!)借助于此,可以调用JavaScript代码,下一个轮询请求会通知这些调用。下面是代码范例:当然,事实确实如此!一旦获得当前页面的名称(DWR知道),就可以获取当前连接到这个页面的所有会话列表。然后,可以获取Util类的一个实例,这个实例是DWR中自己的Java代码和客户端JavaScript代码之间的主要交互点。给这个实例传入一个会话列表,就可以与各个会话进行交互,无须使用集合迭代处理等手段。Util类有很多很方便的方法,其中一个是setValue()。这个方法类似于在客户端执行document.getElementById(divTest).innerHTML = ;,但是它会关注一些细节,比如目标元素是文本框或者其他元素。在此,使用所记录的Date域的当前值来更新divTest的内容。将第三个参数设为true,可以指定任何HTML内容,这样的话不会破坏客户端的任何内容(在此不会带来真正的风险,但是小心处理总比不加限制好)。在轮询Web应用程序中,这部分代码运行在一个线程中,每秒都更新一次时间(和所连接客户端的连接时间)。在J2EE容器中创建线程是不被鼓励的做法,但是作为一个例子演示还是可以的。DWR有个聊天应用程序范例,也是类似的例子。从代码行角度来说,对于当今的多用户聊天应用程序,这个应用程序的代码规模是最小的。如果不希望使用轮询方法,那么可以非常容易地切换为用Comet方法,只需要把web.xml文件中如下代码注释掉:因为Comet是默认方式,我们只需要考虑如何激活它。如果运行这个应用程序,使用Firefox浏览运行结果,以及使用Firebug控制台查看执行进度,就会准确地看到有两个请求。第一个请求发生在页面加载时(很快会被关闭),第二个请求就是反向Ajax线程(Comet),看起来永远不会结束。一个小的微调控制按钮会始终存在,代表着Firebug控制器中的活动。现在,你已经拥有与服务器的持续连接了!最后,为启用piggybacking技术,只需要从web.xml文件删除如下代码行:然后,在index.jsp文件中,添加如下代码:现在,如果加载这个页面,会注意到时间并没有自动改变。但是,每次单击这个按钮时

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论