本速查表基於 WebSocket 協議規範及前端實踐場景整理,涵蓋核心對象屬性、方法、事件回調及錯誤處理方案,適用於日常開發查閲。
一、WebSocket 核心對象與初始化
1. 核心對象
WebSocket:瀏覽器內置構造函數,用於創建 WebSocket 連接實例,是所有操作的基礎。
2. 初始化語法
// 基礎語法:ws(非加密)或 wss(加密,類似 HTTPS)
const socket = new WebSocket('ws://example.com');
// 加密連接示例(生產環境推薦)
const secureSocket = new WebSocket('wss://example.com');
- 參數説明:URL 必須以
ws://或wss://開頭,指向支持 WebSocket 協議的服務器地址。
二、WebSocket 核心屬性
|
屬性名
|
類型
|
説明
|
|
|
數字
|
連接狀態碼:
0 - CONNECTING(連接中)
1 - OPEN(連接已打開)
2 - CLOSING(關閉中)
3 - CLOSED(已關閉)
|
|
|
數字
|
已發送但未被服務器確認的字節數,用於判斷髮送緩衝區是否已滿
|
|
|
字符串
|
實際使用的子協議(若初始化時指定多個協議,返回服務器選中的協議)
|
|
|
字符串
|
創建連接時使用的 URL(只讀)
|
三、WebSocket 核心方法
|
方法名
|
語法
|
説明
|
|
|
|
向服務器發送數據, 注意:連接未打開( |
|
|
|
主動關閉連接;
|
四、WebSocket 核心事件回調
WebSocket 通過“事件驅動”處理連接生命週期,需通過綁定回調函數響應各類狀態變化。
|
事件名
|
綁定方式
|
觸發場景
|
|
|
|
連接成功建立時觸發( |
|
|
|
收到服務器發送的數據時觸發;
通過 |
|
|
|
連接發生錯誤時觸發(如握手失敗、網絡中斷);
注意:錯誤後連接可能自動關閉
|
|
|
|
連接關閉時觸發(主動關閉或被動關閉);
通過 |
五、常見錯誤與解決方案
|
錯誤類型
|
可能原因
|
解決方案
|
|
瀏覽器不支持 WebSocket
|
使用 IE8 及以下等舊瀏覽器
|
檢測 |
|
握手失敗(handshake error)
|
URL 格式錯誤、服務器未支持 WebSocket
|
1. 檢查 URL 前綴是否為 2. 確認服務器已開啓 WebSocket 服務
|
|
連接意外關閉(connection closed)
|
網絡波動、服務器重啓、長時間無數據傳輸
|
在 |
|
發送數據失敗
|
連接未打開( |
1. 發送前檢查 2. 確保數據為字符串/Blob/ArrayBuffer 類型
|
|
連接超時(timeout)
|
網絡延遲高、服務器超時策略
|
實現 Ping/Pong 心跳機制(每 30s 發送 Ping 幀),避免連接被服務器主動斷開
|
六、關鍵狀態碼説明
WebSocket 定義了標準化狀態碼,用於標識連接關閉原因,開發中可通過 event.code 獲取:
|
狀態碼
|
含義
|
場景示例
|
|
1000
|
正常關閉
|
客户端/服務器主動調用 |
|
1001
|
端點離開
|
客户端頁面關閉、服務器下線
|
|
1002
|
協議錯誤
|
數據格式不符合 WebSocket 協議規範
|
|
1003
|
不支持的數據類型
|
發送服務器不支持的數據格式(如二進制數據)
|
|
1005
|
無狀態碼
|
關閉時未指定狀態碼(默認值)
|
|
1006
|
異常關閉
|
網絡中斷、連接意外斷開(無明確原因)
|
七、實戰常用工具函數
1. 連接狀態檢測
// 檢查連接是否可發送數據
function isSocketAvailable(socket) {
return socket && socket.readyState === WebSocket.OPEN;
}
2. 安全發送數據
// 確保連接打開後再發送數據
function safeSend(socket, data) {
if (isSocketAvailable(socket)) {
socket.send(typeof data === 'object' ? JSON.stringify(data) : data);
} else {
console.error('WebSocket 連接未打開,發送失敗');
}
}
3. 心跳機制實現
// 為 socket 添加心跳(每 30s 發送 Ping,5s 未響應則重連)
function addHeartbeat(socket, reconnectFn) {
let heartbeatTimer;
let checkTimer;
// 發送心跳
function sendPing() {
if (isSocketAvailable(socket)) {
socket.send(JSON.stringify({ type: 'ping' }));
// 等待 Pong 響應
checkTimer = setTimeout(() => {
socket.close(1006, '心跳無響應');
reconnectFn(); // 重連函數
}, 5000);
}
}
// 啓動心跳
heartbeatTimer = setInterval(sendPing, 30000);
// 收到 Pong 時清除檢查計時器
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'pong') {
clearTimeout(checkTimer);
}
};
// 關閉時清除計時器
socket.onclose = () => {
clearInterval(heartbeatTimer);
clearTimeout(checkTimer);
};
}