websocket是如何實現握手?

王铁柱6發表於2024-12-10

WebSocket 握手是客戶端和伺服器之間建立 WebSocket 連線的第一步。它本質上是一個 HTTP 請求和響應,用於升級協議從 HTTP 到 WebSocket。以下是握手的具體步驟:

1. 客戶端傳送 WebSocket 握手請求:

客戶端向伺服器傳送一個 HTTP 請求,其中包含一些特殊的頭部資訊,表明它想要升級到 WebSocket 協議。這個請求通常是一個 GET 請求,指向 ws:// 或 wss:// (加密連線) 開頭的 URI。

關鍵的頭部資訊包括:

  • Connection: Upgrade: 表示客戶端希望升級到不同的協議。
  • Upgrade: websocket: 指定要升級到的協議是 WebSocket。
  • Sec-WebSocket-Key: 一個隨機生成的 Base64 編碼的字串,用於防止代理伺服器快取和重用握手。伺服器必須使用這個 key 進行特定的計算並返回結果。
  • Sec-WebSocket-Version: 指定客戶端支援的 WebSocket 協議版本,通常是 13。
  • Origin (可選): 指示請求的來源,用於安全策略。
  • Sec-WebSocket-Protocol (可選): 客戶端支援的子協議列表,伺服器可以選擇其中一個。
  • Sec-WebSocket-Extensions (可選): 客戶端希望使用的擴充套件。

示例請求:

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

2. 伺服器響應 WebSocket 握手請求:

如果伺服器同意建立 WebSocket 連線,它會返回一個 HTTP 101 Switching Protocols 響應。這個響應也包含一些特殊的頭部資訊,確認升級到 WebSocket 協議。

關鍵的頭部資訊包括:

  • Upgrade: websocket: 確認升級到 WebSocket 協議。
  • Connection: Upgrade: 確認連線升級。
  • Sec-WebSocket-Accept: 伺服器根據客戶端提供的 Sec-WebSocket-Key 計算出的值。這是握手過程中至關重要的一步,用於證明伺服器確實收到了客戶端的請求並同意建立 WebSocket 連線。計算方法是將 Sec-WebSocket-Key 與一個固定的 GUID ("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") 連線起來,然後計算 SHA-1 雜湊值,最後將雜湊值進行 Base64 編碼。

示例響應:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

3. 連線建立:

一旦客戶端收到伺服器的 101 響應,WebSocket 連線就建立完成了。客戶端和伺服器就可以開始雙向通訊,傳送和接收 WebSocket 資料幀。

如果握手失敗:

如果伺服器拒絕建立 WebSocket 連線,它會返回一個普通的 HTTP 錯誤響應,例如 400 Bad Request 或 404 Not Found。客戶端可以透過檢查響應的狀態碼來判斷握手是否成功。

前端開發中的 WebSocket 握手:

在前端開發中,通常使用 JavaScript 的 WebSocket API 來建立 WebSocket 連線。開發者無需手動構建 HTTP 請求和解析響應,WebSocket API 會自動處理握手過程。

const socket = new WebSocket('ws://example.com/chat');

socket.onopen = function(event) {
  console.log('WebSocket connection opened');

相關文章