# WebSocket > WebSocket connection management with message handler registration. --- ## Overview The WebSocket module provides connection management, message queuing, automatic reconnection, and handler registration for different message types. --- ## Architecture ``` WebSocket Module ├── websocket (WebSocket instance) ├── msgHandlersMap (type -> handlers mapping) ├── messageQueue (pending messages) ├── openWebSocket() - connect with auto-reconnect ├── closeWebSocket() - graceful disconnect ├── sendSocketMsg() - send with queue fallback └── registerHandler() - subscribe to message types ``` --- ## Connection Management **File**: `/home/hechang27/Documents/sprt/noob-components/plugs/websocket.ts` ### State ```typescript let websocket: WebSocket; const msgHandlersMap = {}; let lastUrl; let closeFlag = false; const messageQueue: any[] = []; ``` | Variable | Type | Description | |----------|------|-------------| | `websocket` | WebSocket | Current WebSocket connection | | `msgHandlersMap` | object | Maps message type to handler objects | | `lastUrl` | string | Last connected URL (for reconnect check) | | `closeFlag` | boolean | Manual close flag (vs auto-reconnect) | | `messageQueue` | array | Queued messages when disconnected | --- ## Core Functions ### openWebSocket Connects to WebSocket URL with auto-reconnect on unexpected close. ```typescript export const openWebSocket = (url) => { if (websocket && websocket.readyState === WebSocket.OPEN) { if (lastUrl == url) { return; // Already connected to same URL } closeWebSocket(); } websocket = new WebSocket(url); lastUrl = url; websocket.onopen = () => { console.log("websocket已连接"); closeFlag = true; // Flush queued messages while (messageQueue.length > 0) { const msg = messageQueue.shift(); websocket.send(JSON.stringify(msg)); } }; websocket.onmessage = (msg) => { const event = JSON.parse(msg.data); const handlers = msgHandlersMap[event.type]; if (!handlers) { return; } Object.values(handlers).forEach((handler: any) => { handler(event.data); }); }; websocket.onclose = () => { console.log("websocket已断开"); if (closeFlag) { // Auto-reconnect after 2 seconds setTimeout(() => { openWebSocket(url); }, 2000); } }; }; ``` ### closeWebSocket Closes connection and prevents auto-reconnect. ```typescript export const closeWebSocket = () => { closeFlag = false; websocket?.close(); }; ``` ### sendSocketMsg Sends message, queues if not connected. ```typescript export const sendSocketMsg = (msg) => { if (websocket && websocket.readyState === WebSocket.OPEN) { websocket.send(JSON.stringify(msg)); } else { messageQueue.push(msg); } }; ``` ### registerHandler Registers handler for a message type. ```typescript export const registerHandler = (type, key, handler) => { const handlers = msgHandlersMap[type] || {}; handlers[key] = handler; msgHandlersMap[type] = handlers; }; ``` --- ## Message Flow ``` 1. openWebSocket(url) | v WebSocket.OPEN | v onopen handler | v Flush messageQueue | v 2. Server sends message | v onmessage handler | v Parse JSON { type, data } | v Lookup msgHandlersMap[type] | v Call all handlers with data ``` --- ## Handler Registration Pattern ```typescript // Register a handler const myHandler = (data) => { console.log('Received:', data); }; registerHandler('refresh', 'myComponent', myHandler); // Later, unregister by setting to null or removing key delete msgHandlersMap['refresh']['myComponent']; ``` --- ## Usage Example ```typescript import { openWebSocket, closeWebSocket, sendSocketMsg, registerHandler, } from './websocket'; // Connect openWebSocket('wss://api.example.com/ws'); // Subscribe to messages registerHandler('refresh', 'dashboard', (data) => { dashboard.update(data); }); registerHandler('notification', 'toast', (data) => { showToast(data.message); }); // Send message sendSocketMsg({ type: 'subscribe', channels: ['refresh', 'notification'] }); // Cleanup on component unmount onUnmounted(() => { delete msgHandlersMap['refresh']['dashboard']; delete msgHandlersMap['notification']['toast']; }); ``` --- ## Auto-Reconnect Behavior - **Unexpected disconnect**: `closeFlag = true` causes auto-reconnect after 2 seconds - **Manual close**: `closeWebSocket()` sets `closeFlag = false` to prevent reconnect - **Same URL check**: Connecting to same URL while already connected is a no-op --- ## Anti-Patterns 1. **Do not register handlers with duplicate keys** - Each key should be unique per type 2. **Do not forget to unregister handlers** - This causes memory leaks and stale handlers 3. **Do not assume messages are always JSON** - Always handle parse errors 4. **Do not send messages before connection** - Messages are queued but check `readyState` if critical --- **Language**: English