WebSocketUtil

帶自動重連、心跳、AES-ECB 解密的 WebSocket 封裝類別。建構即連線,斷線自動重連,伺服器端加密訊息透明解密後分發給所有訂閱者。

運作原理

  1. 建構即 connect():新建 WebSocket,綁定 open / close / error / message。
  2. 心跳:連線建立後每 5 秒發送 'ping' 字串,伺服器回傳的 'pong'(Blob)被識別為心跳回應丟棄。
  3. 訊息解密:非心跳的 Blob 訊息按 hex 密文走 decryptHex(data, options.key) 解密為 JSON 字串再分發;普通 text 訊息直接透傳。
  4. 斷線重連:close / error 觸發重連,延遲 reconnectInterval(預設 3 秒)後重新 connect;顯式 close() 後不再重連。
  5. 多訂閱者:listeners 為自建陣列,add / remove 對稱 API。

API

new WebSocketUtil(options: WebSocketOptions)

interface WebSocketOptions {
  url: string // wss:// 位址
  key: string // AES-ECB 解密金鑰(hex 格式)
  reconnectInterval?: number // 重連間隔 ms,預設 3000
}
實例方法說明
send(data)向伺服器發送字串 / Buffer / Blob;未連線時 console.warn 並丟棄
close()主動關閉(清掉重連計時器與心跳,不再自動重連)
isConnected()readyState === OPEN
addOnMessageListener(fn) / removeOnMessageListener(fn)訂閱 / 退訂訊息(fn(data: string),已解密)
addOnOpenListener(fn) / removeOnOpenListener(fn)訂閱 / 退訂連線建立
addOnCloseListener(fn) / removeOnCloseListener(fn)訂閱 / 退訂連線關閉
addOnErrorListener(fn) / removeOnErrorListener(fn)訂閱 / 退訂連線錯誤

使用範例

// 建立連線並訂閱訊息
const ws = new WebSocketUtil({ url: 'wss://api.example.com/ws', key: wsHexKey })
ws.addOnMessageListener((data) => console.log('recv:', data))

// 登入後發送鑑權幀
ws.addOnOpenListener(() => ws.send(JSON.stringify({ type: 'auth', token })))

// 元件卸載時釋放(退訂 + 關閉,避免洩漏與幽靈重連)
onBeforeUnmount(() => {
  ws.removeOnMessageListener(handler)
  ws.close()
})

注意事項

  • 僅用戶端可用:connect 使用全域 window / WebSocket,請在 onMounted 或 client-only 上下文實例化,SSR 階段不要觸發建構。
  • key 為 hex 字串,與 aes 的 decryptHex 約定一致。
  • 心跳間隔 5s、重連間隔預設 3s;如需調整心跳請擴充本類別,不要魔改私有欄位。
  • 元件級使用務必在卸載時 close() —— 否則實例會在背景無限重連。