WebSocket

WebSocket通讯协议在2011年被IETF定为标准
同时WebSocket API也被W3C定为标准

协议层次关系


WebSocket和Http同为应用层协议,都基于TCP协议。
WebSocket只在建立连接时会利用Http,之后会完全脱离。

协议标识符&端口


WebSocket的URI标识为ws,和http一样也提供TLS加密版本wss
默认端口使用与Http相同,普通是80端口,加密端口443。

握手


Http连接升级,状态码101

1
2
3
Request URL:ws://echo.websocket.org/?encoding=text
Request Method:GET
Status Code:101 Web Socket Protocol Handshake

Request Headers

1
2
3
4
5
6
7
8
9
10
11
12
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:no-cache
Connection:Upgrade
Host:echo.websocket.org
Origin:http://websocket.org
Pragma:no-cache
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
Sec-WebSocket-Key:mA2smwgi7R/XcYahXigNFQ==
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36

Response Headers

1
2
3
4
5
6
7
8
9
10
11
12
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:x-websocket-protocol
Access-Control-Allow-Headers:x-websocket-version
Access-Control-Allow-Headers:x-websocket-extensions
Access-Control-Allow-Headers:authorization
Access-Control-Allow-Headers:content-type
Access-Control-Allow-Origin:http://websocket.org
Connection:Upgrade
Date:Tue, 14 Mar 2017 06:11:07 GMT
Sec-WebSocket-Accept:aY8PSvCZM8PKDgkyMAAyt42ZI2A=
Server:Kaazing Gateway
Upgrade:websocket

典型应用场景:客户端获取实时信息


轮询(Polling)
固定时间间隔查询

  • 请求很多无意义信息
  • 时间间隔小资源消耗大,时间间隔大实时性差

长轮询(Long Polling)
客户端发起请求,服务器无数据就不响应,直到超时或者有数据再返回。客户端立刻发送下一次请求。

  • 更新频繁的话,退化成普通轮询

WebSocket

优势


  • WebSocket是全双工的通讯协议,这也意味着可以实现服务器主动推送消息。
  • 只需一次连接,连接会一直保持。验证信息只在第一次连接时携带。
  • 有状态,无需像Http一样每次会携带沉重的数据包头,节省带宽,实时性好

支持


WebSocket需要多方面的支持

  • 服务端
    服务端要能处理大量打开的连接,因此需要低性能开销,支持高并发的架构,一般采用NIO实现
    Tomcat 8+, Jetty 7+
  • 客户端
    IE 10+, Chrome 31+,FireFox 34+,Android Browser 4.4+
    检测方式
1
2
3
if("WebSocket" in window && WebSocket.CLOSED > 2) {
// support
}
  • 中间层
    代理服务器可能不支持
    WebSocket采用发送Ping/Pong包心跳机制,避免连接长期闲置被路由、防火墙等关闭

WebSocket API


测试网页http://websocket.org/echo.html
WebSocket API是事件响应风格,异步通信

1
2
3
4
5
6
var wsUri = "ws://echo.websocket.org";
var websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { websocket.send("Hello World!"); };
websocket.onclose = function(evt) {};
websocket.onmessage = function(evt) {};
websocket.onerror = function(evt) {};