更多iOS

WebSocket协议简介

2017-02-17  本文已影响37人  kim4apple

WebSocket协议有两部分:握手和数据传输

协议预览

来自客户端的握手

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

来自服务器的握手

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

来自客户端的引导行遵从Request-Line格式,来自服务器的引导行遵从Status-Line格式。Request-Line和Status-Line在[RFC2616]定义。

两种情况下,引导行后面跟着一组未排序的头域。这些头域的意义在本文档第4章指定。额外的头域也可能出现,如cookie[RFC6265]。头格式和解析在[RFC2616]定义。

一旦客户端和服务器都发送了他们的握手。如果握手成功,传输数据部分开始。这是一个双向传输通道,每个端都能独立、随意发送数据。

握手成功后,客户端和服务器来回传输的数据是以消息message为概念单位。在传输介质上(on the wire),一个消息由一个或多个帧frame组成。WebSocket消息不需要对应到特定网络层的帧,业务分帧后的消息可能被中间设施合并或分拆。

一个帧都有一个关联的类型。属于同一个消息的帧拥有相同的数据类型,广义的说,有文本数据(解析为utf-8文本)、二进制数据(他的解析留给了应用程序)和控制帧(不打算携带应用数据,携带的是协议层的信号,如连接关闭信号)类型。

客户端握手

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

服务端握手

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

WebSocket 数据帧格式

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 ...                |
 +---------------------------------------------------------------+
ws-frame                = frame-fin  
                          frame-rsv1  
                          frame-rsv2  
                          frame-rsv3  
                          frame-opcode  
                          frame-masked  
                          frame-payload-length  
                          [ frame-masking-key ]  
                          frame-payload-data  
  
frame-fin               = %x0 ; 表示这不是当前消息的最后一帧,后面还有消息  
                        / %x1 ; 表示这是当前消息的最后一帧  
  
frame-rsv1              = %x0  
                          ; 1 bit, 如果没有扩展约定,该值必须为0  
  
frame-rsv2              = %x0  
                          ; 1 bit, 如果没有扩展约定,该值必须为0  
  
frame-rsv3              = %x0  
                          ; 1 bit, 如果没有扩展约定,该值必须为0  
  
frame-opcode            = %x0 ; 表示这是一个连续帧消息  
                        / %x1 ; 表示文本消息  
                        / %x2 ; 表示二进制消息  
                        / %x3-7 ; 保留  
                        / %x8 ; 表示客户端发起的关闭  
                        / %x9 ; ping(用于心跳)  
                        / %xA ; pong(用于心跳)  
                        / %xB-F ; 保留  
  
frame-masked            = %x0 ; 数据帧没有加掩码,后面没有掩码key  
                        / %x1 ; 数据帧加了掩码,后面有掩码key  
  
frame-payload-length    = %x00-7D  
                        / %x7E frame-payload-length-16  
                        / %x7F frame-payload-length-63  
   ; 表示数据帧的长度  
  
frame-payload-length-16 = %x0000-FFFF  
   ; 表示数据帧的长度  
  
frame-payload-length-63 = %x0000000000000000-7FFFFFFFFFFFFFFF  
   ; 表示数据帧的长度  
  
frame-masking-key       = 4( %0x00-FF ) ; 掩码key,只有当掩码位为1时出现  
  
frame-payload-data      = (frame-masked-extension-data  
                           frame-masked-application-data)   ; 当掩码位为1时,这里的数据为带掩码的数据,扩展数据及应用数据都带掩码  
                        / (frame-unmasked-extension-data  
                           frame-unmasked-application-data) ; 当掩码位为0时,这里的数据为不带掩码的数据,扩展数据及应用数据都不带掩码  
  
frame-masked-extension-data     = *( %x00-FF ) ; 目前保留,以后定义  
  
frame-masked-application-data   = *( %x00-FF )  
  
frame-unmasked-extension-data   = *( %x00-FF ) ; 目前保留,以后定义  
  
frame-unmasked-application-data = *( %x00-FF ) 

引用以下文章

WebSocket Protocol
https://github.com/zhangkaitao/websocket-protocol
WebSocket握手协议
RFC-6455 WebSocket Git-Book

上一篇 下一篇

猜你喜欢

热点阅读