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
- Connects in the constructor: creates the WebSocket and binds open / close / error / message.
- Heartbeat: once connected, sends the string
'ping'every 5 seconds; the server's'pong'(a Blob) is recognized as a heartbeat response and dropped. - 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. - Reconnect: close / error triggers a reconnect after
reconnectInterval(default 3s); an explicitclose()disables further reconnects. - 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 method | Notes |
|---|---|
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:
connectuses the globalwindow/WebSocket— instantiate insideonMountedor a client-only context; never construct during SSR. keyis a hex string, matching thedecryptHexconvention 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.