首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

反向 Ajax,第 1 部分 Comet 简介(1)

反向 Ajax,第 1 部分 Comet 简介(1)

简介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 请求示例
1
2
3
4
5
6
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 使用了 JSONP 来通过邮政编码获取地名。JSONP 请求通常可通过它的回调参数和返回内容识别出来,这些内容是可执行的 JavaScript 代码。
要在 JavaScript 中实现轮询,您可以使用 setInterval 来定期地发出 Ajax 请求,如清单 2清单 2 所示:
清单 2. 清单 2 JavaScript 轮询
1
2
3
4
5
setInterval(function() {
    $.getJSON('events', function(events) {
        console.log(events);
    });
}, 2000);




中的轮询演示给出了轮询方法所消耗的带宽,间隔很小,但可以看到有些请求并未返回事件,清单 3清单 3 给出了这一轮询示例的输出。
清单 3. 清单 3 轮询演示例子的输出
1
2
3
4
5
6
7
8
9
[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 实现的轮询的优点和缺点。
  • 优点:很容易实现,不需要任何服务器端的特定功能,且在所有的浏览器上都能工作。
  • 缺点:这种方法很少被用到,因为它是完全不具伸缩性的。试想一下,在 100 个客户端每个都发出 2 秒钟的轮询请求的情况下,所损失的带宽和资源数量,在这种情况下 30% 的请求没有返回数据。
Piggyback捎带轮询 (piggyback polling) 是一种比轮询更加聪明的做法,因为它会删除掉所有非必需的请求(没有返回数据的那些)。不存在时间间隔,客户端在需要的时候向服务器端发送请求。不同之处在于响应的那部分上,响应被分成两个部分:对请求数据的响应和对服务器事件的响应,如果任何一部分有发生的话。图 2图 2 给出了一个例子。
图 2. 使用了 piggyback 轮询的反向 Ajax在实现 piggyback 技术时,通常针对服务器端的所有 Ajax 请求可能会返回一个混合的响应。 中有一个实现示例,如下面的清单 4清单 4 所示。
清单 4. 清单 4 piggyback 代码示例
1
2
3
4
5
6
7
8
$('#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 输出示例
1
2
3
4
5
6
7
[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




您可以看到表单验证的结果和附加到响应上的事件。同样,这种方法也有着一些优点和缺点。
  • 优点:没有不返回数据的请求,因为客户端对何时发送请求做了控制,对资源的消耗较少。该方法也是可用在所有的浏览器上,不需要服务器端的特殊功能。
  • 缺点:当累积在服务器端的事件需要传送给客户端时,您却一点都不知道,因为这需要一个客户端行为来请求它们。
返回列表