websocket

烂柯人發表於2021-06-23

1、什麼是 webSocket 協議
HTML5 開始提供的一種瀏覽器與伺服器進行全雙工通訊的網路技術,屬於應用層協議。它基於 TCP 傳輸協議,並複用 HTTP 的握手通道。
2、webSocket 的應用
伺服器向客戶端推送訊息的場景需求,比如實時更新日誌、客服聊天、聯網的遊戲、直播互動等等,有時需要瀏覽器端的使用者一直保持點對點通訊,此情此景,最好的選擇是 websocket,因為從穩定性、伺服器資源開銷都是最優的。
特點:
WebSocket 可以在瀏覽器裡使用
支援雙向通訊
優點:
支援雙向通訊,實時性更強
對比 http 協議,支援雙向統信、更靈活、高效、可擴充性好
更好地二進位制支援
較少的控制開銷,建立連線後,客戶端與服務端進行資料交換是,協議控制的資料包頭部較小,在不包含頭部的情況下,服務端到客戶端的包頭只有 2~1-位元組。
與 http 不同點:
HTTP 的協議識別符號是 http,websocket 的是 ws
HTTP 請求只能由客戶端發起,伺服器無法主動向客戶端推送訊息,而 websocket 可以
HTTP 請求有同源限制,不同源之間通訊需要跨域,而 websocket 沒有同源限制
與 http 相同點:
都是應用層的通訊協議
預設埠一樣,都是 80 或 443
都可以用於瀏覽器和伺服器間的通訊
都基於 TCP 協議



3、連線過程
如何建立連線
資料幀格式
如何交換資料
如何維持連線
建立連線
客戶端發起 HTTP 請求,經過 3 次握手建立 TCP 連線,HTTP 請求裡存放 WebSocket 支援的版本號等資訊。2.伺服器收到客戶端握手請求後,回饋資料。
以上兩個步驟完成後,HTTP 握手部分完成,協議升級為 WebSocket,此時伺服器就不再需要客戶端發起請求,再響應請求了,可以主動推送資訊給客戶端了。
只需要一次連線就可以做到源源不斷的資訊傳遞了

1)客戶端:申請協議升級
webSocket 複用了 HTTP 的握手通道。具體指的是,客戶端透過 HTTP 請求與 WebSocket 服務端協商升級協議。協議升級完成後,後續的資料交換則遵照 WebSocket 的協議

GET / HTTP/1.1
Host: localhost:8080
Origin: http://127.0.0.1:3000
Connection: Upgrade 表示要升級協議

Upgrade: websocket 表示升級到 webSocket 協議

Sec-WebSocket-Version: 13 支援的版本號,服務端不支援則返回對應支援的版本號
Sec-WebSocket-Key: w4v7O6xFTi36lq3RNcgctw==

2)服務端:響應協議升級

HTTP/1.1 101 Switching Protocols 101 表示協議切換完成協議升級
Connection:Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: Oy4NRAQ13jhfONC7bP8dTKb4PTU=
將 Sec-WebSocket-Key 與符號拼接,透過 sha1 計算然後轉讓 base64 字串

資料幀格式
客戶端、服務端資料的交換、離不開資料幀格式的定義,websocket 客戶端、服務端通訊的最小單位是幀(frame)
傳送端將資訊切割成多個幀,併傳送給服務端
接收端,接受訊息幀,並將關聯的幀重新組裝成完整的訊息

交換資料
一旦 WebSocket 客戶端、服務端建立連線後,後續的操作都是基於資料幀的傳遞。WebSocket 根據 opcode 來區分操作的型別。比如 0x8 表示斷開連線,0x0-0x2 表示資料互動
Websocket 的每條休息可能會被分割成多個資料幀,當接收方接收到一個資料幀時,會根據 FIN 的值來判斷,是否已經收到了訊息的最後一個資料幀。FIN=1 表示當前資料幀是訊息的最後一個資料幀,接收方已經收到完整的訊息,可以對訊息進行處理。FIN=0 時,接收方還需要繼續監聽其餘的資料幀。
此外,opcode 表示資料型別,0x01 表示文字,ox02 表示二進位制,0x00 表示延續幀當前的資料幀需要接在上一條資料幀之後
例項:
Client: FIN=1, opcode=0x1, msg="hello"
Server: (process complete message immediately) Hi.
Client: FIN=0, opcode=0x1, msg="and a
"Server: (listening, new message containing text started)
Client: FIN=0, opcode=0x0, msg="happy new"
Server: (listening, payload concatenated to previous message)
Client: FIN=1, opcode=0x0, msg="year!"
Server: (process complete message) Happy new year to you too!

連線保持 + 心跳

連線斷開了
連線沒斷連線不可用
連線對端的服務不可用

相關文章