In this lesson, you will learn how to architect a lightweight publish-subscribe (pub-sub) service to route targeted push notifications to specific user sessions over WebSockets.
The Pub-Sub Pattern for Notifications
When building a notification system, you rarely want to broadcast every message to every connected client. Instead, you need a way to map specific users to their active WebSocket connections. The most efficient way to handle this is by implementing a central NotificationManager that acts as a registry.
Designing the Registry
Your system needs two things: a map to track which socket belongs to which userId, and a simple messaging interface to trigger events.
class NotificationManager {
constructor() {
this.userSessions = new Map(); // userId -> WebSocket
}
register(userId, socket) {
this.userSessions.set(userId, socket);
}
send(userId, message) {
const socket = this.userSessions.get(userId);
if (socket && socket.readyState === 1) { // 1 = OPEN
socket.send(JSON.stringify({ type: 'NOTIFICATION', payload: message }));
}
}
}
Decoupling with Events
To keep the system responsive, avoid coupling your database logic directly to your socket logic. Instead, use Node.js EventEmitter. When an event occurs (like a "new comment" or "order update"), your system emits a generic notification event. The NotificationManager listens for these events, checks if the recipient is online in the userSessions map, and pushes the data only to that specific connection.
This architecture ensures that even if you have thousands of connected clients, the server isn't iterating through every socket to find the right one; it performs a O(1) lookup in the userSessions Map. Because you have already learned about handling concurrency and memory usage, ensure that when a socket closes, you clean up the map to prevent memory leaks and "dangling" references that could cause silent errors.
Key Takeaway: A decoupled pub-sub notification system maps user IDs to active socket instances, allowing for targeted, O(1) delivery of real-time updates without burdening unconnected clients.