[date: 2019-02-24 00:11] [visits: 20]

WebSocket备忘

记些websocket的知识备忘。

对比HTTP优势

websocket与HTTP一样,都是建立TCP之上的应用层协议,它较于HTTP的优点主要有以下两点:

HTTP不允许服务端主动向client发送数据,websocket在设计之初着重考虑了这个问题,所以websocket支持全双工通信,服务端可以主动给客户端推送消息

连接建立过程

websocket作为HTTP不能主动推送的替代方案,其连接建立过程却依赖HTTP完成,主要原因是为了与现有HTTP基础设施兼容。使用HTTP建立连接可以复用80和443端口,因为这两个端口是被认可的,不太可能出现被中间设备或服务器防火墙拦截的情况。

通过HTTP建立连接的好处除了复用端口外,可以重用HTTP的Upgrade流,并扩展HTTP头部字段完成建立连接的信息协商。

握手过程

建立连接的握手过程主要是以下两步:

当上诉握手步骤成功完成后,表明websocket连接建立完成,接下来的数据通信开始由websocket协议接管。

扩展头部

部分扩展头部的含义如下:

客户端利用该头部携带一次性的值来验证接收到的请求服务器是否支持websocket协议,假设某代理缓存了一次握手请求的响应,当另一个client再次请求握手时,该代理没有再次请求服务器而返回了上一个请求的响应,这时客户端能判断出当前链路不支持websocket协议,从而关闭连接

响应头,用于配合Sec-WebSocket-Key,服务器对client传过来的Key进行签名(配合一个全球唯一的GUID),再使用该头部携带传给客户端表明支持websocket协议

用于商议websocket通信的子协议,具体规则是client通过该头部提供一个备选列表,服务器从中选择自己支持的一个传回给client

数据帧

websocket协议通信的数据帧的结构如下:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

帧结构说明:

掩码的作用可以防止恶意脚本拥有tcp socket权限,避免攻击中间设备的可能,具体可以参考这篇文章