WebSocket通訊的握手、傳輸、心跳到關閉,底層到底在做什麼?這篇把整個過程拆開來看。
WebSocket是什麼?
WebSocket是一種網路通訊協定,能在瀏覽器和伺服器之間建立全雙工的通訊管道。傳統HTTP是請求—回應模式,每次都要重新建立連線;WebSocket一旦握手完成,雙方就可以隨時互相傳送訊息,連線一直維持著。
WebSocket通訊過程
1. 建立連線
客戶端(通常是瀏覽器)先發出一個普通的 HTTP GET 請求,帶上升級用的標頭:
1 | Upgrade: websocket |
Sec-WebSocket-Key 是瀏覽器隨機產生的 16 bytes,經 base64 編碼後放進去,作用是讓伺服器證明它確實理解 WebSocket 協定。
2. 伺服器回應
伺服器若支援 WebSocket,回傳 HTTP 101(Switching Protocols):
1 | Upgrade: websocket |
Sec-WebSocket-Accept 的計算方式:把客戶端的 key 和固定 GUID 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 串接後,SHA-1 雜湊,再 base64 編碼。這個設計是為了防止不懂 WebSocket 的 HTTP 代理或快取意外完成握手。
3. 連線建立完成
客戶端驗證 Sec-WebSocket-Accept 正確後,握手完成。從這一刻起,HTTP 協定退場,同一條 TCP 連線就變成 WebSocket 通道。
4. 資料傳輸
WebSocket 用「幀(Frame)」傳資料,幀標頭記錄了類型(文字或二進位)和長度。有一個細節值得注意:客戶端送往伺服器的幀必須做遮罩(masking),遮罩金鑰是每幀隨機產生的 32 bits;伺服器回傳的幀則不需要遮罩。這是 RFC 6455 強制規定的,伺服器收到沒有遮罩的客戶端幀必須直接關閉連線。
雙方都可以在不等待對方回應的情況下傳資料,這就是全雙工的意思。
5. 心跳機制
長時間沒有流量時,NAT 或防火牆可能靜悄悄地把連線砍掉。WebSocket 的 Ping/Pong 控制幀就是用來偵測這件事:任何一方都可以發 Ping,對方收到後必須立刻回 Pong。實務上通常是伺服器定期對所有連線發 Ping,超時沒收到 Pong 就主動關閉,釋放資源。
6. 關閉連線
關閉是有序的四步握手:
- 任何一方發出帶狀態碼的關閉幀
- 另一方收到後,回一個關閉幀
- 雙方都確認後,底層 TCP 連線才正式關閉
這樣可以確保兩端都知道連線結束,避免資料在關閉過程中遺失。
和 HTTP 輪詢相比
傳統做法是讓前端每隔幾秒發一次 HTTP 請求問「有新資料嗎?」,每次都要建立連線、帶上完整的 HTTP 標頭、等待回應,就算伺服器沒有新東西也是一樣的成本。
WebSocket 握手只做一次,之後的每筆訊息只有幾個 bytes 的幀標頭,伺服器也可以主動推資料,不用等客戶端來問。對需要高頻更新的場景,這個差距很明顯。
適用場景
WebSocket特別適合需要即時更新的應用,例如:
- 線上遊戲
- 即時聊天室
- 股票行情顯示器
- 線上協作工具




