Live notifications via Server-Sent Events

Node · Node · intermediate · modification

Upgrades the notifications endpoint from a one-shot snapshot to a live SSE stream. Sets the event-stream headers, flushes them so the browser opens the stream immediately, subscribes to the shared notificationBus, and forwards each event addressed to this user as an SSE frame. Verified against a browser EventSource — notifications show up the instant they fire.

notificationBus is a single process-wide EventEmitter shared by the whole app. Every open browser tab holds one SSE connection, and users open, close, and refresh tabs constantly, so this handler runs on every reconnect against the same long-lived bus.

Requirements

Files touched

--- src/routes/notifications-stream.js
-const { getUnread } = require('../services/notifications');
+const bus = require('../events/notification-bus');
 
-// GET /notifications/stream — one-shot JSON snapshot of the user's unread notifications.
-async function streamNotifications(req, res) {
-  const unread = await getUnread(req.user.id);
-  res.writeHead(200, { 'Content-Type': 'application/json' });
-  res.end(JSON.stringify({ unread }));
+// GET /notifications/stream — Server-Sent Events feed of the user's live notifications.
+function streamNotifications(req, res) {
+  res.writeHead(200, {
+    'Content-Type': 'text/event-stream',
+    'Cache-Control': 'no-cache',
+    Connection: 'keep-alive',
+  });
+  res.flushHeaders();
+
+  const onNotification = (event) => {
+    if (event.userId !== req.user.id) return;
+    res.write(`event: notification\ndata: ${JSON.stringify(event)}\n\n`);
+  };
+
+  bus.on('notification', onNotification);
 }
 

Review this PR

Node practice