反向 Ajax,第 1 部分: Comet 简介
用于服务器与客户端之间响应通信的流和长轮询在过去的几年里,Web 开发已经发生了很大变化。现如今,我们期望的是能够通过 Web 快速、动态地访问应用。在这一新的文章系列中,我们学习如何使用反向 Ajax (Reverse Ajax) 技术来开发事件驱动的 Web 应用,以此来实现更好的用户体验。 客户端的示例使用的是 jQuery JavaScript 库。在这首篇文章中,我们探索不同的反向 Ajax 技术,使用可下载的例子来学习使用了流 (streaming) 方法和长轮询 (long polling) 方法的 Comet。
简介Web 开发在过去的几年中有了很大的进展,我们已经远超了把静态网页链接在一起的做法,这种做法会引起浏览器的刷新,并且要等待页面的加载。现在需要的是能够通过 Web 来访问完全动态的应用。 这些应用通常需要尽可能的快,提供近乎实时的组件。在这个分为 5 部分的新系列中,我们学习如何使用反向 Ajax (Reverse Ajax) 技术来开发事件驱动的 Web 应用。 在这第一篇文章中,我们要了解反向 Ajax、轮询 (polling)、流 (streaming)、Comet 和长轮询 (long polling)。学习如何实现不同的反向 Ajax 通信技术,并探讨每种方法的优点和缺点。 您可以下载本文中例子的相应源代码。 Ajax、反向 Ajax 和 WebSockets异步的 JavaScript 和 XML (Ajax),一种可通过 JavaScript 来访问的浏览器功能特性,其允许脚本向幕后的网站发送一个 HTTP 请求而又无需重新加载页面。 Ajax 的出现已经超过了十年,尽管其名字中包含了 XML,但您几乎可以在 Ajax 请求中传送任何的东西。最常使用的数据是 JSON,它与 JavaScript 语法非常接近且消耗更少的带宽。 清单 1清单 1 给出了这样的一个例子,Ajax 请求通过某个地方的邮政编码来检索该地的名称。 清单 1. 清单 1 Ajax 请求示例var url = 'http://www.geonames.org/postalCodeLookupJSON?postalcode=' + $('#postalCode').val() + '&country=' + $('#country').val() + '&callback=?'; $.getJSON(url,function(data) { $('#placeName').val(data.postalcodes[0].placeName); }); 在本文可下载的源代码中,您可在 listing1.html 中看到这一例子的作用。 反向 Ajax (Reverse Ajax) 本质上则是这样的一种概念:能够从服务器端向客户端发送数据。在一个标准的 HTTP Ajax 请求中,数据是发送给服务器端的,反向 Ajax 可以某些特定的方式来模拟发出一个 Ajax 请求,这些方式本文都会论及,这样的话,服务器就可以尽可能快地向客户端发送事件(低延迟通信)。 WebSocket 技术来自 HTML5,是一种最近才出现的技术,许多浏览器已经支持它(Firefox、Google Chrome、Safari 等等)。WebSocket 启用双向的、全双工的通信信道,其通过某种被称为 WebSocket 握手的 HTTP 请求来打开连接,并用到了一些特殊的报头。连接保持在活动状态,您可以用 JavaScript 来写和接收数据,就像是正在用一个原始的 TCP 套接口一样。WebSocket 会在这一文章系列的第二部分中谈及。 反向 Ajax 技术反向 Ajax 的目的是让服务器将信息推送到客户端。Ajax 请求默认情况下是无状态的,且只能从客户端向服务器端发出请求。您可以通过使用技术模拟服务器端和客户端之间的响应式通信来绕过这一限制。 HTTP 轮询和 JSONP 轮询轮询 (Polling) 涉及了从客户端向服务器端发出请求以获取一些数据,这显然就是一个纯粹的 Ajax HTTP 请求。为了尽快地获得服务器端事件,轮询的间隔(两次请求相隔的时间)必须尽可能地小。但有这样的一个缺点存在:如果间隔减小的话,客户端浏览器就会发出更多的请求,这些请求中的许多都不会返回任何有用的数据,而这将会白白地浪费掉带宽和处理资源。 图 1 图 1 中的时间线说明了客户端发出了某些轮询请求,但没有信息返回这种情况,客户端必须要等到下一个轮询来获取两个服务器端接收到的事件。 图 1. 使用 HTTP 轮询的反向 AjaxJSONP 轮询基本上与 HTTP 轮询一样。不同之处在于使用 JSONP 您可以发送跨域请求(请求不属于您所在的域)。清单1清单 1使用了 JSONP 来通过邮政编码获取地名。JSONP 请求通常可通过它的回调参数和返回内容识别出来,这些内容是可执行的 JavaScript 代码。 要在 JavaScript 中实现轮询,您可以使用 清单 2. 清单 2 JavaScript 轮询setInterval(function() {
$.getJSON('events',function(events) {
console.log(events);
});
},2000);
文章源代码中的轮询演示给出了轮询方法所消耗的带宽,间隔很小,但可以看到有些请求并未返回事件,清单 3清单 3 给出了这一轮询示例的输出。 清单 3. 清单 3 轮询演示例子的输出[client] checking for events...
[client] no event
[client] checking for events...
[client] 2 events
[event] At Sun Jun 05 15:17:14 EDT 2011
[event] At Sun Jun 05 15:17:14 EDT 2011
[client] checking for events...
[client] 1 events
[event] At Sun Jun 05 15:17:16 EDT 2011
用 JavaScript 实现的轮询的优点和缺点。
Piggyback捎带轮询 (piggyback polling) 是一种比轮询更加聪明的做法,因为它会删除掉所有非必需的请求(没有返回数据的那些)。不存在时间间隔,客户端在需要的时候向服务器端发送请求。不同之处在于响应的那部分上,响应被分成两个部分:对请求数据的响应和对服务器事件的响应,如果任何一部分有发生的话。图 2图 2 给出了一个例子。 图 2. 使用了 piggyback 轮询的反向 Ajax在实现 piggyback 技术时,通常针对服务器端的所有 Ajax 请求可能会返回一个混合的响应。文章的下载中有一个实现示例,如下面的清单 4清单 4 所示。 清单 4. 清单 4 piggyback 代码示例$('#submit').click(function() {
$.post('ajax',function(data) {
var valid = data.formValid;
// process validation results
// then process the other part of the response (events)
processEvents(data.events);
});
});
清单 5清单 5 给出了一些 piggyback 输出。 清单 5. 清单 5 piggyback 输出示例[client] checking for events...
[server] form valid ? true
[client] 4 events
[event] At Sun Jun 05 16:08:32 EDT 2011
[event] At Sun Jun 05 16:08:34 EDT 2011
[event] At Sun Jun 05 16:08:34 EDT 2011
[event] At Sun Jun 05 16:08:37 EDT 2011
您可以看到表单验证的结果和附加到响应上的事件。同样,这种方法也有着一些优点和缺点。
Comet使用了轮询或是捎带的反向 Ajax 非常受限:其不具伸缩性,不提供低延迟通信(只要事件一到达服务器端,它们就以尽可能快的速度到达浏览器端)。Comet是一个 Web 应用模型,在该模型中,请求被发送到服务器端并保持一个很长的存活期,直到超时或是有服务器端事件发生。在该请求完成后,另一个长生存期的 Ajax 请求就被送去等待另一个服务器端事件。使用 Comet 的话,Web 服务器就可以在无需显式请求的情况下向客户端发送数据。 Comet 的一大优点是,每个客户端始终都有一个向服务器端打开的通信链路。服务器端可以通过在事件到来时立即提交(完成)响应来把事件推给客户端,或者它甚至可以累积再连续发送。因为请求长时间保持打开的状态,故服务器端需要特别的功能来处理所有的这些长生存期请求。图 3图 3 给出了一个例子。(本系列的第 2 部分会更详细地解释服务器端的约束条件。) 图 3. 图 3.使用 Comet 的反向 AjaxComet 的实现可以分成两类:使用流 (streaming) 的那些和使用长轮询 (long polling) 的那些。 回页首 使用 HTTP 流的 Comet 在流 (streaming) 模式中,有一个持久连接会被打开。只会存在一个长生存期请求(图 3图 3 中的 #1),因为每个到达服务器端的事件都会通过这同一连接来发送。因此,客户端需要有一种方法来把通过这同一连接发送过来的不同响应分隔开来。从技术上来讲,两种常见的流技术包括 Forever Iframe(或者 hidden IFrame),或是被用来在 JavaScript 中创建 Ajax 请求的 Forever Iframes Forever Iframe(永存的 Iframe)技术涉及了一个置于页面中的隐藏 Iframe 标签,该标签的
多部分的
|
描述 | 名字 | 大小 |
---|---|---|
文章源代码 | reverse_ajaxpt1_source.zip | 17KB |
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!