HTML5 WebSockets是HTML5中最强大的通信功能,它定义了一个全双工的通信信道,仅通过Web上的一个Socket即可进行通信。Websockets不仅是对常规HTTP通信的另一种增量加强,它更代表着一次巨大的进步,对实时的、事件驱动的Web应用程序而言更是如此。
6.1 HTML5 WebSockets概述
6.1.1 实时和HTTP
目前实时Web应用的实现方式,大部分是围绕轮询和其他服务器推送技术展开的,其中最著名的是Comet。Comet技术可以让服务器端主动以异步方式向客户端推送数据,它会使针对传输消息到客户端的响应延迟完成。
使用轮询时,浏览器会定期发送HTTP请求,并随即接受响应。这项技术是浏览器在实时信息传送方面的首次尝试。显然,如果知道消息传递的准确时间间隔,轮询将是一个很好的办法,因为可以将客户端的请求同步为只有服务器上的信息是可用时才发出。但是,实时数据往往不可预测,不可避免会产生一些不必要的请求,在低消息率情况下会有很多的连接不断地打开和关闭。
使用长轮询时,浏览器向服务器发送一个请求,服务器会在一段时间内将其保持在打开状态。如果服务器在此期间收到一个通知,就会向客户端发送一个包含消息的响应。如果时间已到却还没收到通知,服务器会发送一个响应消息来终止打开的请求。然而,最关键的是,当信息量很大时,与传统轮询方式相比,长轮询方式并无实质上的性能改善。
使用流解决方案时,浏览器会发送一个完整的HTTP请求,但服务器会发送并保持一个处于打开状态的响应,该响应持续更新并无限期(或是一段时间内)处于打开状态。每当有消息可发送时该响应就会被更新,但服务器用用不会发送响应完成的信号,这样连接就会一直保持在打开状态以便后续消息的发送。但是,由于流仍是封装在HTTP中,期间防火墙和代理服务器可能会对响应消息进行缓冲,造成消息床底的时延。因此,当检测到缓冲代理服务器时,许多流解决方案就回退到长轮询方式。此外,可利用TLS(SSL)连接来保护响应不被缓冲,但在这种情况下,每个连接的创建和清除会消耗更多的服务器资源。
6.1.2 解读HTML5 WebSockets
1.WebSockers握手
为了建立WebSocket通信,客户端和服务器在初始握手时,将HTTP协议升级到WebSocket协议。
WebSocket升级握手
从客户端到服务器:
GET /demo HTTP/1.1
Host:example.com
Connection:Upgrade
Sec-WebSocket-Key2:12998 5 y3 1 .poo
Sec-WebSocket-Protocol:sample
Upgrade:WebSocket
Sec-WebSocket-Key1:4@1 45546xW%01 1 5
Origin:http://example.com
[8-byte security key]
从服务器到客户端:
HTTP/1/1 101 WebSocket Protocol Handshake
Upgrade:WebSocket
Connection:Upgrade
WebSocket-Origin:http://example.com
WebSocket-Location:ws://example.com/demo
WebSocket-Protocol:sample
[16-byte hash response]
一旦连接建立成功,就可以在全双共模式下在客户端和服务器之间来回传送WebSocket消息。这就意味着,在同一时间、任何方向,都可以全双工发送给予文本的消息。在网络中,每个消息以0x00字节开头,以0xFF结尾,中间数据采用UTF-8编码格式。
2.WebSocket接口
除了对WebSocket协议的定义外,该规范同事还定义了用于JavaScript应用程序的WebSocket接口。
[Constructor(in DOMSting url,in optional DOMString protocol)]
interface WebSocket{
//就绪状态
readonly attribute DOMString URL;
const unsigned short CONNECTING=0;
const unsigned short OPEN=1;
const unsigned short CLOSED=2;
readonly attribute unsigned short readyState;
readonly attribute unsigned long bufferedAmount;
//网络
attribute Function onopen;
attribute Function onmessage;
attribute Function onclose;
boolean send(in DOMString data);
void close();
};
WebSocket implements EventTarget;
WebSocket接口的使用很简单。要连接远程主机,只需要新建一个WebSocket实例,提供希望连接的对端URL。注意,ws://和wss://前缀分别表示WebSocket连接和安全的WebSocket连接。
基于同一底层的TCP/IP连接,在客户端和服务器之间的初始握手阶段,将HTTP协议升级至WebSocket协议,WebSocket连接就建立完成了。连接一旦建立,WebSocket数据帧就可以以全双工模式在客户端和服务器之间进行双向传送。连接本身是通过WebSocket接口定义的message事件和send函数来运作的。在代码中,采用异步事件侦听器来控制连接生命周期的每一个阶段。
myWebSocket.onopen=function(evt){alert("Connection open…")};
myWebSocket.onmessage=function(evt){alert("Received Message:"+evt.data);};
myWebSocket.onclose=function(eve){alert("Connection closed")};
3.大幅消减不必要的网络流量和时延
6.2 HTML5 WebSockets的浏览器支持情况
6.3 编写简单的Echo WebSocket服务器
6.4 使用HTML5 WebSockets API
6.4.1 浏览器支持情况检测
6.4.2 API的基本用法
1.WebSocket对象的创建及其与WebSocket服务器的连接
WebSocket接口的使用非常简单。要连接通信端点,只需要创建一个新的WebScocket实例,并提供希望连接的对端URL。ws://和wss://前缀分别表示WebSocket连接和安全的WebSocket连接。
2.添加事件监听器
WebSocket编程遵循异步编程模型;打开socket后,只需要等待事件发送,而不需要主动向服务器轮询,所以需要在WebSocket对象中添加回调函数来监听事件。
WebSocket对象有三个事件:open、close和message。当连接建立时触发open事件,当收到消息时触发message事件,当WebSocket连接关闭时触发close事件。同大多数Javascript API一样,事件处理时会调用响应的(onopen、onmessage、onclose)回调函数。
3.发送消息
当socket处于打开状态(即调用onopen监听程序之后,调用onclose监听程序之前),可以采用send方法来发送消息。消息发送完成之后,可以调用close方法来终止连接,当然也可以不这么做,让其保持打开状态。
4.运行WebSocket页面
6.5 创建HTML5 WebSocket应用程序
<!--EndFragment-->