WebSocket-Learning-1

WebSocket

1.什麼是WebSocket

WebSocket 是一種通訊協議,目標就是替代XmlHttpRequest 和長期輪詢的解決方案。應用在實時彈幕、消息推送、棋牌遊戲、聊天等需要及時通訊的場景。

2.WebSocket 連接有兩個階段

握手(handshake)和數據傳輸(data transfer)

3.客戶端發送握手請求
  • Uri 格式
    ws-URI=ws://host[:port]path[?query]
    例如:ws://localhost:10020/
  • 在與服務端建立連接時,客戶端必鬚髮送握手請求,請求是一個http升級協議(Upgrade)請求。並且該請求必須滿足:
    (1) 握手請求必須是一個正常的HTTP請求。
    (2) 請求方法必須爲GET,並且HTTP協議最低爲1.1
    (3)請求頭必須包含Host
    (4)請求頭必須包含Upgrade,並且值爲websocket
    (5)請求頭必須包含Connection,並且值爲Upgrade
    (6)請求頭必須包含Sec-WebSocket-Key,值爲經過Base64轉換的長度爲16字節的一組數據
    (7)請求頭必須包含Origin,如果客戶端是瀏覽器這個值肯定是有的,如果非瀏覽器的客戶端,這個值可以隨意改。
    (8)請求頭必須包含Sec-WebSocket-Version,並且值爲13
    (9)請求頭可以帶一個Sec-WebSocket-Protocol,這個值告訴服務端客戶端想用的子協議,多個用逗號分開
    (10)請求頭可以帶一個Sec-WebSocket-Extensions,這個值告訴服務端客戶端支持的協議級別的擴展。
    (11)請求頭可以帶一個和權限校驗相關的頭,例如Cookie,Authentication等
  • 示例:

Http Upgrade請求

 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

當客戶端將握手請求發出去之後,就要等待服務端的響應。當服務端響應成功之後,客戶端還需要做如下校驗

  1. 返回的響應碼非101,例如401,500,403,503 等等,客戶端連接失敗
  2. 返回的響應頭部不包含Upgrade或者Upgrade的值不是websocket,客戶端連接失敗
  3. 返回的響應頭部不包含Connection或者Connection的值不是Upgrade,客戶端連接失敗
  4. 返回的響應頭部不包含Sec-WebSocket-Accept或者Sec-WebSocket-Accept的值並不是Base64(SHA1(Sec-WebSocket-Key+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11")),客戶端連接失敗
  5. 返回的響應頭部Sec-WebSocket-Extensions中的值並不是客戶端發送的Sec-WebSocket-Extensions中的值,客戶端連接失敗
  6. 返回的響應頭部Sec-WebSocket-Protocol中的值並不是客戶端發送的Sec-WebSocket-Protocol中的值,客戶端連接失敗
服務端接收握手請求

如果服務端在處理請求過程中不滿足以下任何一項,服務端都會終止處理該請求

  1. 必須是HTTP1.1+的GET請求
  2. 包含Host請求頭
  3. 包含Upgrade值爲WebSocket的請求頭
  4. 包含Connection值爲Upgrade的請求頭
  5. 包含Sec-WebSocket-Key值爲16字節長度的Base64字符串
  6. 包含Sec-WebSocket-Version值爲13的請求頭
  7. 非必須:Origin
  8. 非必須:Sec-WebSocket-Protocol
  9. 非必須:Sec-WebSocket-Extensions

當服務端確定這是一個正常的握手請求並且願意處理此請求,那麼服務端需要回應一個HTTP響應:

  1. 狀態碼必須爲 101 Switching Protocol
  2. Upgrade:WebSocket
  3. Connection:Upgrade
  4. Sec-WebSocket-Accept,如上文所說,值爲:Base64(SHA1(Sec-WebSocket-Key+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))
  5. Sec-WebSocket-Protocol,根據客戶端傳的值
  6. Sec-WebSocket-Extensions,根據客戶端傳的值
    至此,握手結束。連接狀態由CONNECTING進入OPEN狀態
協議幀

WebSocket的協議幀格式如下:
WebSocket協議

FIN 1bit
包結束標誌,1 代表最後一個消息包,0代表某一段消息包
RSV1, RSV2, RSV3: 每個1bit,共3bit
值爲0,除非協議擴展(Extensions)聲明瞭非0的值的含義。如果服務端收到非0的值,並且沒有相應的定義,那麼服務端將直接終止連接。
Opcode 4bit
x0 後續幀
x1 文本幀
x2 二進制幀
x3-X7 非控制幀預留
x8 關閉連接
x9 PING
xA PONG
xB-xF 控制幀預留
Mask 1 bit 是否掩碼。客戶端向服務器發送,必須掩碼。服務端向客戶端發送不需掩碼
PayLoad Length 7bits,7+16bits,7+64bits,如果值爲 0-125,則數據包長度爲0-125.如果值爲126,則後2個字節爲數據包長度:16bit。如果值爲127,則後8個字節爲數據包長度:64bit。
Masking-Key, 0-4bits.是否有值取決於 Mask 標識位是否爲1.
Extension data X bytes 如果在握手時協商了擴展,會有值,否則爲0
Application data y bytes 剩餘消息包
PayLoad data (x+y)bytes 總消息包=Extension data + Application data.如果有掩碼,解碼公式如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章