1. WebSocket
WebSocket为“浏览器-服务器” 模型中提供简单易用的双向通信机制的技术 ,和”长、短轮询“机制相比,能节省带宽和减少延时。目前主流浏览器已经支持了WebSocket技术,目前支持情况见下图:
更加详细的信息,包括各浏览器市场占有份额:http://caniuse.com/#search=websocket
访问方式url:
ws-URI = ws://host [:port ]/path?”query ] // 默认端口为80,不提供ssl加密
wss-URI = wss://host [:port ]/path?”query ] // 默认端口为443,提供ssl加密
2. WebSocket协议介绍
WebSocket(简称ws)协议的RFC规范为RFC6455
WS协议分成两种类型:握手和数据传输。
2.1 WS握手
握手部分的设计目的就是兼容现有的基于 HTTP 的服务端组件(web 服务器软件)或者中间件(代理服务器软件)。这样一个端口就可以同时接受普通的 HTTP 请求或则 WebSocket 请求了。为了这个目的,WebSocket 客户端的握手是一个 HTTP 升级版的请求(HTTP Upgrade request)。
[source lang=”html”]
GET /chat HTTP/1.1 # 必须为 HTTP/1.1,测试中发现也可以为1.0
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
[/source]
服务回应样例如下:
[source lang=”html”]
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= // client请求 Sec-WebSocket-Key
// 的SHA1摘要的base64编码值
[/source]
2.2 WS数据传输
在 WebSocket 协议中,数据的传输使用一连串的帧。为了使得中间件不至于混淆(比如代理服务器)以及为了安全原因,客户端必须将要发送到服务端的帧进行掩码。(注意,不管 WebSocket 有没有运行在 TLS 之上,都必须有掩码操作)服务端一旦接收到没有进行掩码的帧的话,必须关闭连接。这种情况下,服务端可以发送一个关闭帧,包含一个状态码 1002(协议错误 protocol error)。服务端不必对发送到客户端的任何帧进行掩码。如果客户端接收到了服务端的掩码后的帧,客户端必须关闭连接。

2.2.1 FIN
标记这个帧是不是消息中的最后一帧。第一个帧也可以是最后一帧。
2.2.2 op code
- %x0 表示这是一个继续帧(continuation frame)
- %x1 表示这是一个文本帧 (text frame)
- %x2 表示这是一个二进制帧 (binary frame)
- %x3-7 为将来的非控制帧(non-control frame)而保留的
- %x8 表示这是一个连接关闭帧 (connection close)
- %x9 表示这是一个 ping 帧
- %xA 表示这是一个 pong 帧
- xB-F 为将来的控制帧(control frame)而保留的
2.2.3 Mask
定义了 “有效负荷数据” 是否是被掩码的。如果被设置为 1,那么在 masking-key
部分将有一个掩码钥匙(masking key),并且使用这个掩码钥匙去将 “有效负荷数据” 进行反掩码操作。所有的由客户端发往服务端的帧此数位都被设置成 1。