WebSocketUtil

A WebSocket wrapper class with auto-reconnect, heartbeat, and AES-ECB decryption. Connects on construction, reconnects on disconnection, and transparently decrypts encrypted server messages before fanning them out to all subscribers.

How It Works

  1. Connects in the constructor: creates the WebSocket and binds open / close / error / message.
  2. Heartbeat: once connected, sends the string 'ping' every 5 seconds; the server's 'pong' (a Blob) is recognized as a heartbeat response and dropped.
  3. Message decryption: non-heartbeat Blob messages are treated as hex ciphertext and decrypted via decryptHex(data, options.key) into a JSON string before dispatch; plain text messages pass through untouched.
  4. Reconnect: close / error triggers a reconnect after reconnectInterval (default 3s); an explicit close() disables further reconnects.
  5. Multiple subscribers: listeners are stored in plain arrays with symmetric add / remove APIs.

API

new WebSocketUtil(options: WebSocketOptions)

interface WebSocketOptions {
  url: string // wss:// address
  key: string // AES-ECB decryption key (hex format)
  reconnectInterval?: number // reconnect delay in ms, default 3000
}
Instance methodNotes
send(data)Send a string / Buffer / Blob; console.warn + drop when not connected
close()Close deliberately (clears reconnect timer and heartbeat; no further reconnects)
isConnected()readyState === OPEN
addOnMessageListener(fn) / removeOnMessageListener(fn)Subscribe / unsubscribe to messages (fn(data: string), already decrypted)
addOnOpenListener(fn) / removeOnOpenListener(fn)Subscribe / unsubscribe to connection open
addOnCloseListener(fn) / removeOnCloseListener(fn)Subscribe / unsubscribe to connection close
addOnErrorListener(fn) / removeOnErrorListener(fn)Subscribe / unsubscribe to connection errors

Examples

// Connect and subscribe to messages
const ws = new WebSocketUtil({ url: 'wss://api.example.com/ws', key: wsHexKey })
ws.addOnMessageListener((data) => console.log('recv:', data))

// Send an auth frame after login
ws.addOnOpenListener(() => ws.send(JSON.stringify({ type: 'auth', token })))

// Release on component unmount (unsubscribe + close, avoiding leaks and ghost reconnects)
onBeforeUnmount(() => {
  ws.removeOnMessageListener(handler)
  ws.close()
})

Caveats

  • Client only: connect uses the global window / WebSocket — instantiate inside onMounted or a client-only context; never construct during SSR.
  • key is a hex string, matching the decryptHex convention in aes.
  • Heartbeat interval is 5s, reconnect default 3s; to tweak the heartbeat, extend this class rather than poking private fields.
  • For component-scoped usage, always close() on unmount — otherwise the instance keeps reconnecting in the background forever.