WebSocket是一种通过单个TCP连接提供全双工通信信道的协议。2011年,IETF将WebSocket协议标准化为RFC 6455,W3C正在对Web IDL中的WebSocket API进行标准化。
WebSocket通信由消息和应用程序代码组成,不需要担心缓冲、解析和重构接收到的数据。例如,如果服务器发送1MB的有效负载,则只有当整个消息在客户端上可用时,才会调用应用程序的onmessage回调。
此外,WebSocket协议不对应用程序有效负载进行任何假设和约束:文本和二进制数据都是公平的游戏。在内部,协议只跟踪两个部分
当浏览器接收到新消息时,它会自动转换为基于文本的数据的DOMString对象,或二进制数据的Blob对象,然后直接传递给应用程序。唯一的其他选项,作为客户端的性能提示和优化,是告诉浏览器将接收到的二进制数据转换为ArrayBuffer而不是Blob:
一旦建立了WebSocket连接,客户端就可以随意发送和接收UTF-8和二进制消息。WebSocket提供双向通信信道,允许通过同一TCP连接在两个方向上传递消息:
Example traffic示例流量
Connection setup连接设置
To establish a WebSocket connection, the client sends a WebSocket handshake request, for which the server returns a WebSocket handshake response, as shown in the example below.为了建立WebSocket连接,客户端发送一个WebSocket握手请求,服务器将为该请求返回一个WebSocket握手响应,如下例所示。
Client request (just like in HTTP, each line ends with \r\n
and there must be an extra blank line at the end):客户端请求(就像在HTTP中一样,每一行都以\r\n结尾,并且结尾必须有一个额外的空行):
GET / HTTP/1.1 Host: 192.168.43.135:12345 Connection: Upgrade Pragma: no-cache Cache-Control: no-cache Upgrade: websocket Origin: file:// Sec-WebSocket-Version: 13 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4 Sec-WebSocket-Key: bKdPyn3u98cTfZJSh4TNeQ== Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Server response:服务器响应:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: 4EaeSCkuOGBy+rjOSJSMV+VMoC0= WebSocket-Origin: file:// WebSocket-Location: ws://192.168.43.135:12345/
Data transmission数据传输
Here is an example of data transmission between a Python WebSocket Server and JavaScript client.下面是Python WebSocket服务器和JavaScript客户端之间的数据传输示例。
An example from server to client:从服务器到客户端的示例:
Frame 7: 79 bytes on wire (632 bits), 79 bytes captured (632 bits) Ethernet II, Src: Vmware_8a:3d:a7 (00:0c:29:8a:3d:a7), Dst: Vmware_c0:00:08 (00:50:56:c0:00:08) Internet Protocol Version 4, Src: 192.168.43.135, Dst: 192.168.43.1 Transmission Control Protocol, Src Port: 12345, Dst Port: 50999, Seq: 205, Ack: 510, Len: 25 WebSocket 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 0001 = Opcode: Text (1) 0... .... = Mask: False .001 0111 = Payload length: 23 Payload JavaScript Object Notation Line-based text data Welcome, 192.168.43.1 !
An example from client to server:从客户端到服务器的示例:
Frame 9: 72 bytes on wire (576 bits), 72 bytes captured (576 bits) Ethernet II, Src: Vmware_c0:00:08 (00:50:56:c0:00:08), Dst: Vmware_8a:3d:a7 (00:0c:29:8a:3d:a7) Internet Protocol Version 4, Src: 192.168.43.1, Dst: 192.168.43.135 Transmission Control Protocol, Src Port: 50999, Dst Port: 12345, Seq: 510, Ack: 230, Len: 18 WebSocket 1... .... = Fin: True .000 .... = Reserved: 0x0 .... 0001 = Opcode: Text (1) 1... .... = Mask: True .000 1100 = Payload length: 12 Masking-Key: e17e8eb9 Masked payload Payload JavaScript Object Notation Line-based text data test message
参考文件:
https://hpbn.co/websocket/
https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
https://www.rfc-editor.org/rfc/rfc6455
https://wiki.wireshark.org/WebSocket.md