如何实现类似Socket.IO的WebSocket动态消息事件监听功能?
.on() Method) Got it, let's fix this! The problem with your static switch statement is that it's baked into the code once you write it—you can't easily add new cases later. But we can replicate Socket.IO's flexible event pattern using vanilla JavaScript, no libraries needed.
Here's the Step-by-Step Solution:
Instead of relying on a switch, we'll use an object to store event handlers by their type. This lets us dynamically add/remove handlers whenever we want, just like Socket.IO.
1. Set Up the WebSocket and Handler Map
First, replace your hardcoded onmessage with a dynamic handler that checks our map:
const socket = new WebSocket('ws://your-server-endpoint'); // This object will store all our event handlers: key = event type, value = array of handlers const eventHandlers = {}; // Override the default onmessage to use our handler map socket.onmessage = function(event) { try { // Parse the incoming message (same as your original code) const message = JSON.parse(event.data); // Important: Your original code used `event.type`—that's a mistake! // The WebSocket MessageEvent's `type` is always "message". You want the type FROM your message payload. const eventType = message.type; // If there are handlers for this event type, run all of them if (eventHandlers[eventType]) { eventHandlers[eventType].forEach(handler => handler(message)); } } catch (err) { console.error('Error processing message:', err); } };
2. Add .on() and .off() Methods (Just Like Socket.IO)
Now we'll add methods to the socket object to dynamically register and unregister handlers:
// Mimic Socket.IO's .on() method to add a handler socket.on = function(eventType, handler) { // Create an array for this event type if it doesn't exist if (!eventHandlers[eventType]) { eventHandlers[eventType] = []; } // Add the handler to the array eventHandlers[eventType].push(handler); }; // Optional: Add an .off() method to remove a handler socket.off = function(eventType, handler) { // If no handlers exist for this type, do nothing if (!eventHandlers[eventType]) return; // Filter out the specific handler eventHandlers[eventType] = eventHandlers[eventType].filter(h => h !== handler); // Clean up the key if there are no handlers left if (eventHandlers[eventType].length === 0) { delete eventHandlers[eventType]; } };
3. Use It Just Like Socket.IO!
Now you can add event handlers whenever you want—even dynamically after the socket connects:
// Initial static handlers (like your original switch cases) socket.on('UPDATE_USER', (message) => { // Your user update logic here console.log('Updating user:', message); }); socket.on('UPDATE_FOO', (message) => { // Your FOO update logic here console.log('Updating FOO:', message); }); // Dynamically add a new handler later (like your example) socket.on('ADD_NEW_DYNAMIC_CASE', (message) => { // Your dynamic action logic here console.log('Handling new dynamic case:', message); });
Why This Works:
- The
eventHandlersobject acts as a lookup table for all our event types. - Every time a message comes in, we check if there are handlers registered for its type, then run them all.
- The
.on()method lets us add new handlers anytime, without modifying the originalonmessagecode.
Quick note: Make sure your server sends messages with a type field (like { "type": "UPDATE_USER", ... }) so our code can pick up the event type correctly.
内容的提问来源于stack exchange,提问作者Jonathan Chevalier

