websocket通信原理

http通訊只能一來一回,不能直接回包,因而出現了websocket實時通信web

背景

在websocket沒有出現以前,總會有一些需求,須要獲取數據,可是這些數據殊不知道哪一個時間點才能獲取到,因而,你們使用了輪詢來解決服務器推送的問題。瀏覽器

HTTP協議只能從客戶端發出請求,服務器處理返回請求(這裏能夠看下圖),可是服務器不能主動給客戶端發送請求,因而解決服務器推送的問題,就只能靠輪詢了。服務器

輪詢分爲兩種websocket

  • 短輪詢:定時發送http請求socket

  • 長輪詢:發送請求直到收到消息or超時後繼續發送下一個請求加密

可是,輪詢並不能完美的解決服務器推送的問題spa

  • 服務器沒法主動發送數據
  • 輪詢實時性差
  • 輪詢浪費較多資源

概念

websocket的出現,就是爲了解決服務器推送的問題。3d

WebSocket是HTML5開始提供的一種在單個 TCP 鏈接上進行全雙工(通訊雙方既是接收方也是發送方,兩端設備能夠同時發送和接收數據)通信的協議。code

特性

  • 創建在TCP連接之上
  • 較少的控制開銷
  • 更強的實時性
  • 保持鏈接狀態
  • 能夠發送文本、二進制數據
  • 沒有同源限制

連接過程

websocket的連接仍是比較簡單的,只要進行一次握手,就能夠進行後續的通信了,這裏分爲三步:cdn

  1. http get請求將http請求升級爲websocket請求
  2. 數據通信
  3. 斷開連接(可由任一方中斷)

握手協議

在第一步的時候進行了握手,這裏來看一下請求的詳情

// 請求
GET / HTTP/1.1
Upgrade: websocket // 升級爲websocket協議
Connection: Upgrade 
Host: localhost:3000 // 請求host
Origin: http://binnie.com // 請求來源
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ== // 用於後續計算accept
Sec-WebSocket-Version: 13 // websocket版本號

複製代碼
// 回包
HTTP/1.1 101 Switching Protocols // 101表示連接成功
Upgrade: websocket // 與請求對應
Connection: Upgrade
// 使用key計算得來,儘可能避免普通HTTP請求被誤認爲Websocket協議
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s= 
複製代碼

幀格式

WebSocket協議使用幀(Frame)收發數據

客戶端發送給服務端的幀必須經過4字節的掩碼(Masking-key)加密,服務端收到消息後,用掩碼對數據幀的Payload Data進行異或運算解碼獲得數據,若是服務端收到未經掩碼加密的數據幀,則應該立刻關閉該WebSocket。

服務端發給客戶端的數據則不須要掩碼加密,客戶端若是收到了服務端的掩碼加密的數據,則也必須關閉它。

上圖爲websocket的幀格式,下面咱們一個個來分析

這裏從左往右看,橫向爲32位(bit)

  • FIN:最後的片斷
  • RSV1-3:拓展定義
  • opcode:幀類型,其中控制幀:0x8 (Close), 0x9 (Ping), and 0xA (Pong),數據幀主要有:0x1 (Text), 0x2 (Binary)
  • MASK:數據是否掩碼
  • Payload len:負載長度
  • Extended payload length:拓展負載長度
  • Masking-key:掩碼
  • Playload Data:負載數據

因此,websocket傳遞數據時最小的請求頭爲 FIN+RSV1-3+opcode+MASK+Payload len+Masking-key = 6 byte(字節),剩下的就都是實際數據,相比於http頭部小得多。

兼容性

websocket是很好的實時雙向通信,不過兼容性只到ie10,因此不支持websocket的瀏覽器就只能使用輪詢等方法來兼容。

寫在最後

因爲低版本瀏覽器不支持websocket,須要使用輪詢來兼容,因而出現了不少websocket庫,後面再分析websocket庫的實現。

相關文章
相關標籤/搜索