歡迎光臨
每天分享高質量文章

一文讀懂 WebSocket 通信過程與實現

來源:Python那些事

ID:PythonSomething

什麼是 WebSocket ?

WebSocket 是一種標準協議,用於在客戶端和服務端之間進行雙向資料傳輸。但它跟 HTTP 沒什麼關係,它是一種基於 TCP 的一種獨立實現。

以前客戶端想知道服務端的處理進度,要不停地使用 Ajax 進行輪詢,讓瀏覽器隔個幾秒就向服務器發一次請求,這對服務器壓力較高。另外一種輪詢就是採用 long poll 的方式,這就跟打電話差不多,沒收到訊息就一直不掛電話,也就是說,客戶端發起連接後,如果沒訊息,就一直不傳回 Response 給客戶端,連接階段一直是阻塞的。

而 WebSocket 解決了 HTTP 的這幾個難題。首先,當服務器完成協議升級後( HTTP -> WebSocket ),服務端可以主動推送信息給客戶端,解決了輪詢造成的同步延遲問題。由於 WebSocket 只需要一次 HTTP 握手,服務端就能一直與客戶端保持通訊,直到關閉連接,這樣就解決了服務器需要反覆解析 HTTP 協議,減少了資源的開銷。

隨著新標準的推進,WebSocket 已經比較成熟了,並且各個瀏覽器對 WebSocket 的支持情況比較好,有空可以看看。

使用 WebSocket 的時候,前端使用是比較規範的,js 支持 ws 協議,感覺類似於一個輕度封裝的 Socket 協議,只是以前需要自己維護 Socket 的連接,現在能夠以比較標準的方法來進行。

客戶端請求報文及實現

客戶端請求報文:

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

與傳統 HTTP 報文不同的地方:

Upgrade: websocket Connection: Upgrade

這兩行表示發起的是 WebSocket 協議。

Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

Sec-WebSocket-Key 是由瀏覽器隨機生成的,提供基本的防護,防止惡意或者無意的連接。

Sec-WebSocket-Version 表示 WebSocket 的版本,最初 WebSocket 協議太多,不同廠商都有自己的協議版本,不過現在已經定下來了。如果服務端不支持該版本,需要傳回一個 Sec-WebSocket-Versionessay-header,裡面包含服務端支持的版本號。

創建 WebSocket 物件:

var ws = new websocket("ws://127.0.0.1:8001");

ws 表示使用 WebSocket 協議,後面接地址及端口


完整的客戶端代碼:

分享創造快樂