反向Ajax:WebSockets一个强大的解决方案

本文还将讨论在服务器端使用反向 Ajax 技术的一些制约因素。
现在,用户期望可以从 Web 访问快速、动态的应用程序。本 系列 文章展示了如何使用反向 Ajax 技术开发事件驱动的 Web 应用程序。反向 Ajax,第 1 部分:Comet 简介 介绍了反向 Ajax、轮询、流、Comet 和长轮询。您应该已经了解到,使用 HTTP 长轮询的 Comet 是可靠地实现反向 Ajax 的最佳方式,因为现在所有浏览器都提供了这方面的支持。
通过本文,您将学习如何使用 WebSockets 实现反向 Ajax。代码示例有助于说明 WebSockets、FlashSockets、服务器端的制约因素、请求作用域服务和暂停长期请求。
先决条件
在理想的情况下,如果想最大限度地利用本文,您应该了解 JavaScript 和 Java。本文创建的示例是使用 Google Guice 构建的,Google Guice 是用 Java 编写的依赖项注入框架。要理解本文内容,则需要熟悉依赖项注入框架的概念,比如 Guice、Spring 或 Pico。
要运行本文中的示例,还需要使用最新版的 Maven 和 JDK。
WebSockets
WebSockets 在 HTML5 中出现,是比 Comet 更新的反向 Ajax 技术。WebSockets 支持双向、全双工通信信道,而且许多浏览器(Firefox、Google Chrome 和 Safari)也支持它。连接通过 HTTP 请求(也称为 WebSockets 握手)和一些特殊的标头 (header)。连接一直处于激活状态,您可以用 JavaScript 编写和接收数据,正如您使用原始 TCP 套接字一样。
通过输入 ws:// 或 wss://(在 SSL 上)启动 WebSocket URL。
图 1 中的时间轴展示了如何使用 WebSockets 进行通信。HTTP 握手被发送到带有特定标头的服务器。然后,可在 JavaScript 的服务器或客户端上提供某种类型的套接字。可使用该套接字来通过事件处理器异步接收数据。
图 1. 通过 WebSockets 执行反向 Ajax


在本文的 下载源代码 中有一个 WebSocket 示例。当您运行该示例时,就会到类似于 清单 1 的输出。它显示了事件如何发生在服务器端上,并立即出现在客户端。当客户端发送一些数据时,服务器将其反映在客户端上。
清单 1. 用 JavaScript 编写的 WebSocket 示例



[client] WebSocket connection opened
[server] 1 events
[event] ClientID = 0
[server] 1 events
[event] At Fri Jun 17 21:12:01 EDT 2011
[server] 1 events
[event] From 0 : qqq
[server] 1 events
[event] At Fri Jun 17 21:12:05 EDT 2011
[server] 1 events
[event] From 0 : vv

通常,在 JavaScript 中使用 WebSockets 的方式与 清单 2 中展示的相同(如果您的浏览器支持它)。
清单 2. JavaScript 客户端代码



var ws = new WebSocket('ws://127.0.0.1:8080/async');
ws.onopen = function() {
    // called when connection is opened
};
ws.onerror = function(e) {
    // called in case of error, when connection is broken in example
};
ws.onclose = function() {
    // called when connexion is closed
};
ws.onmessage = function(msg) {
    // called when the server sends a message to the client.
    // msg.data contains the message.
};
// Here is how to send some data to the server
ws.send('some data');
// To close the socket:
ws.close();

可以发送和接收任何类型的数据。WebSockets 可被看作是 TCP 套接字,因此由客户端和服务器决定要发送的数据类型。这里给出的示例发送的是 JSON 字符串。
在创建了 JavaScript WebSocket 对象后,如果在浏览器的控制台(或 Firebug)深入查看 HTTP 请求中的握手,您应该看到特定于 WebSocket 的包头。