什么是websocket
WebSocket是web浏览器和服务器之间的一种全双工通信协议,其中WebSocket协议由IETF定位标准,WebSocket API由W3C定位标准。一旦Web客户端与服务器建立起连接,之后的全部数据通信都通过这个连接进行。通信过程中,支持发送JSON、XML、HTML或图片等任意格式的数据。
WS(WebSocket)与HTTP协议相比
相同点主要有:
- 都是基于TCP的应用层协议;
- 都使用Request/Response模型进行连接的建立;
- 在连接的建立过程中对错误的处理方式相关,在这阶段WS可能返回和HTTP相同的返回码
- 都可以在网络中传输数据
不同之处在于:
- WS使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用;
- WS的连接不能通过中间人来转发,它必须是一个直接连接——那网关如何转发?分别建立 client-网关、网关-upstream的连接?
- WS连接建立之后,通信双方都可以在任何时刻向另一方发送数据;
- WS连接建立之后,数据的传输使用帧来传递,不再需要Request消息
- WS的数据帧有序
主要特点
- 推送功能:服务器可以直接向客户端推送消息。
- 减少通信量:只要第一次建立连接,就可以一直进行通信,不像HTTP协议,需要频繁的建立请求,一问一答的模式。此外,WebSocket的头部数据也比较少。
握手协议
websocket是基于TCP的一个应用协议,与HTTP协议的关联之处在于websocket的握手数据被HTTP服务器当作HTTP包来处理,主要通过update request HTTP包建立起连接,之后的通信全部使用websocket自己的协议。
请求:TCP连接建立后,客户端发送websocket的握手请求,请求报文头部如下:
GET /chat HTTP/1.1
Host: server.example.com
**Upgrade: websocket**
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: https://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
- 第一行为请求的方法,类型必须为GET,协议版本号必须大于1.1
- Upgrade字段必须包含,值为websocket
- Connection字段必须包含,值为Upgrade
- Sec-WebSocket-Key字段必须包含,记录着握手过程中必不可少的键值。
- Sec-WebSocket-Protocol字段必须包含,记录者使用的自协议
- Origin:作安全使用,防止跨站攻击,浏览器一般会使用这个来标志原始域。
响应:服务器接收到请求后,返回状态码101 Switching Protocols的响应。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
- Sec-WebSocket-Accept字段是由握手请求中的Sec-WebSocket-Key字段生成的。
握手成功后,通信不再使用HTTP协议,而采用WebSocket独立的数据帧。
websocket连接关闭状态码表
状态码 | 名称 | 描述 |
---|---|---|
0-999 | 保留段,未使用 | |
1000 | CLOSE_NORMAL | 正常关闭 |
1001 | CLOSE_GOING_AWAY | 终端离开,可能因为服务端错误,也可能因为浏览器正从打卡连接的页面跳转离开 |
1002 | CLOSE_PROTOCOL_ERROR | 由于协议错误而断开连接 |
1003 | CLOSE_SUPPORTED | 由于收到不允许的数据而断开连接(例如:仅接收文本数据的终端接收了二进制数据) |
1004 | 保留 | |
1005 | CLOSE_NO_STATUS | 保留 . 表示没有收到预期的状态码. |
1006 | CLOSE_ABNORMAL | 保留 . 用于期望收到状态码时连接非正常关闭 (也就是说, 没有发送关闭帧). |
1007 | Unsupported Data | 由于收到了格式不符的数据而断开连接 |
1008 | Policy Violation | 由于收到不符合约定的数据而断开连接 |
1009 | CLOSE_TOO_LARGE | 由于收到过大的数据帧而断开连接 |
1010 | Missing Extension | 客户端期望服务器商定一个或者多个拓展,但服务器没有处理,因此客户端断开连接。 |
1011 | Internal Error | 客户端由于遇到没有预料的情况阻止其完成请求, 因此服务端断开连接. |
1012 | Service Restart | 服务由于重启断开连接 |
1013 | Try Again Later | 服务器由于临时原因断开连接 |
1015 | TLS Handshake | 保留. 表示连接由于无法完成 TLS 握手而关闭 (例如无法验证服务器证书). |
详见:https://wdd.js.org/websocket-close-reasons.html
附录
附录1: 全双工VS单工
-
全双工(Full Duplex):是通信传输的一个术语。通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。全双工指可以同时(瞬时)进行信号的双向传输(A-》B且B-》A)。例如,电话。
-
半双工(Half Duplex):指一个时间段内只有一个动作发生。例如:对讲机。
-
单工:就是只允许甲方向乙方传送信息,而乙方不能向甲方传送。
附录2: Python Websockets Module has no attribute
报错:
AttributeError: module 'websocket' has no attribute 'WebSocket'
ws = websocket.WebSocket()
原因:安装错module,应该安装 websocket_client,而不是websocket
参考:https://stackoverflow.com/questions/40212252/python-websockets-module-has-no-attribute