WebSocket

546 阅读3分钟

一、简述及一些参考文档

WebSocket是设计用来实现单个TCP连接上全双工通信的协议。(通俗一点说,就是建立一个TCP连接后,客户端和服务端都可以主动向对端发送数据)。WebSocket是HTML5中定义的,主要用于网页请求。

WebSocket草案中文版感觉翻译得不太行。。。

WebSocket草案英文版

二、WebSocket的一些基本点

  • 与HTTP的兼容性: 先看一下一个很简单的WebSocket示例
    图一
图一、客户端请求示例

图二

图二、服务端响应示例
  1. 基于http协议建立连接,借用http协议完成握手。我们从图一、图二中可以看到,请求是以http请求的方式发出,不过增加了UpgradeConnectionSec-WebSocket-KeySec-WebSocket-Version字段。服务器接收到后会切换到WebSocket协议并进行支持。
  2. 与http共享TCP端口,默认情况下的80和TLS加密情况下的443
  • 与HTTP对比
特征 HTTP WebSocket
连接时效 无持久连接,通过keep-alive保持连接 持久连接
通信方式 单向请求和响应 全双工通信
状态 无状态,服务端不记录客户端信息 有状态
发起连接方 客户端 客户端
关闭连接方 客户端 双端
控制开销 较大
请求及响应数
总TCP连接数 一样 一样
实时性
二进制支持
拓展性 可以设计并使用一些子协议,在请求中指定
压缩率 较低
  • RFC6455规范要求WebSocket版本均使用13,此之前各浏览器设计开发的版本都不再使用。
  • WebSocket与HTTP轮询的比较:都是建立一次TCP连接(如果http轮询没有超时的话),但HTTP轮询会由客户端每隔一定时间发送HTTP请求,服务器对请求返回响应,WebSocket则是只发送一次请求,当服务端有更新的时候,无需等待客户端的新请求,可以主动向客户端推送数据。

三、WebSocket规范中的一些重要点

1.连接断开机制

双端都可以主动发起断开连接。发起方发送一个control frame来告知对方(我想要断开连接啦,从此以后我不会再给你发别的数据,不过我还能接收你的数据),接受方回应一个close frame(好的,断开吧,我从此以后不发送也不接收你的数据了)。

由上面的流程可以看出,在断开连接的过程中,发起方仍能接收对方数据,直到整个连接确认断开。所以比起原有的TCP挥手,是更为安全可靠的。

2.握手

如图一和图二,

  • 如果WebSocket请求来自于浏览器客户端,必须包含Origin的头域;如果客户端不是浏览器,可以根据Origin是否有用来决定要不要包含。
  • 请求中可能包含名为Sec-WebSocket-Protocol的头域,用于指定所选的子协议。
  • 请求可能包含名为Sec-WebSocket-Extensions的头域。
  • 客户端发送握手请求后,必须等待服务端的握手响应,才能继续发送其他数据。且需按协议规范决定该次握手是否成功(如果握手响应不规范则认为握手失败)。
  • 服务端接收握手请求后,必须解析并确认该请求符合规范,才能发送握手响应。除此之外,服务端可以执行额外的客户端验证。发送完握手响应后,服务端认为该连接已成功建立,可以开始发送和接收数据了。

3.帧格式

WebSocket中数据使用ABNF描述,如下图三。

图三

图三、WebSocket帧格式