一、简述及一些参考文档
WebSocket是设计用来实现单个TCP连接上全双工通信的协议。(通俗一点说,就是建立一个TCP连接后,客户端和服务端都可以主动向对端发送数据)。WebSocket是HTML5中定义的,主要用于网页请求。
WebSocket草案中文版感觉翻译得不太行。。。
二、WebSocket的一些基本点
- 与HTTP的兼容性:
先看一下一个很简单的WebSocket示例
- 基于http协议建立连接,借用http协议完成握手。我们从图一、图二中可以看到,请求是以http请求的方式发出,不过增加了Upgrade、Connection、Sec-WebSocket-Key、Sec-WebSocket-Version字段。服务器接收到后会切换到WebSocket协议并进行支持。
- 与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描述,如下图三。