这一文章系列探讨了如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用,第1部分内容介绍了实现反向Ajax通信的几种不同方式:轮询(polling)、捎带(piggyback)以及使用了长轮询(long-polling)和流(streaming)的Comet。在本文中,我们学习一种新的实现反向Ajax的技术:使用WebSocket,一个新的HTML5 API。WebSocket可由浏览器厂商来做本地化实现,或是通过把调用委托给隐藏的被称为FlashSocket的Flash组件这种桥接手段来实现。本文还讨论了反向Ajax技术带来的一些服务器端约束。
前言
时至今日,用户期待的是可通过web访问快速、动态的应用。这一文章系列展示了如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用。该系列的第1部分介绍了反向Ajax、轮询(polling)、流(streaming)、Comet和长轮询(long polling)。你已经了解了Comet是如何使用HTTP长轮询的,这是可靠地实现反向Ajax的最好方式,因为现有的所有浏览器都提供支持。
在本文中,我们将学习如何使用WebSocket来实现反向Ajax。代码例子被用来帮助说明WebSocket、FlashSocket、服务器端约束、请求作用域(request-scoped)服务以及暂停长生存期请求等,你可以下载本文中用到的这些源代码。
前提条件
理想情况下,要充分体会本文的话,你应该对JavaScrpit和Java有一定的了解。本文中创建的例子是使用Google Guice来构建的,这是一个使用Java编写的依赖注入框架。若要读懂文中所谈内容,你应该要熟悉诸如Guice、Spring或是Pico一类的依赖注入框架的概念。
若要运行本文中的例子,你还需要最新版本的Maven和JDK(参见参考资料)。
WebSocket
在HTML5中出现的WebSocket是一种比Comet还要新的反向Ajax技术,WebSocket启用了双向的全双工通信信道,许多浏览器(Firefox、Google Chrome和Safari)都已对此做了支持。连接是通过一个被称为WebSocket握手的HTTP请求打开的,其用到了一些特殊的报头。连接会保持在活动状态,你可以使用JavaScript来写入和接收数据,就像是在使用一个原始的TCP套接口一样。
WebSocket URL的起始输入是ws://或是wss://(在SSL上)。
图1中的时间线说明了使用WebSocket的通信。一个带有特定报头的HTTP握手被发送到了服务器端,接着在服务器端或是客户端就可以通过JavaScript来使用某种套接口(socket)了,这一套接口可被用来通过事件句柄异步地接收数据。
图1. 使用WebSocket的反向Ajax
本文可下载的源代码中有一个WebSocket例子,在运行该例子时,你应该会看到类似清单1的输出。其说明了客户端的事件是如何发生的,以及如何会立即在客户端显示出来。当客户端发送一些数据时,服务器端回应客户端的发送行为。
清单1. JavaScript中的WebSocket例子
server 1 events
event ClientID = 0
At Fri Jun 17 21 : 12 01 EDT 2011 From : qqq
05 : vv
通常情况下,在JavaScript中你会如清单2所说明的那样来使用WebSocket,如果你的浏览器支持它的话。
清单2. JavaScript客户端例子
发送和接收的数据可以是任意类型的,WebSocket可被看成是TCP套接口,因此这取决于客户端和服务器端知道要来回发送的数据是哪种类型的。这里的例子发送的是JSON串。
在JavaScript WebSocket对象被创建后,如果在浏览器的控制台(或是Firebug)中仔细看一下HTTP请求的话,你应该会看到WebSocket特有的报头。清单3给出了一个例子。
清单3. HTTP请求和相应报头示例
Request Method:GET
Status Code: 101 WebSocket Protocol Handshake
Request Headers
Connection:Upgrade
Host:
Origin:http://localhost:
Sec-WebSocket-Key1: & ~ 33188Yd]r8dp W75q
Sec-WebSocket-Key2: 7 ; 229 *043M 8 Upgrade:WebSocket
(Key3):B4:BB: 20 37 45 :3F:BC:C7
Response Headers
Connection:Upgrade
Sec-WebSocket-Location:ws:// /async
Sec-WebSocket-Origin:http://localhost:
Upgrade:WebSocket
(Challenge Response):AC: 23 :A5:7E:5D:E5: 04 :6A:B5:F8:CC:E7:AB:6D:1A: 39