Files
radiusNucleo/node-api/src/sse.js
josedario87 c5a1c6aaf0
All checks were successful
build-and-deploy / build (push) Successful in 9s
build-and-deploy / deploy (push) Successful in 15s
fix
2025-09-26 20:57:10 -06:00

59 lines
1.7 KiB
JavaScript

import { MAX_REQUESTS } from './config/env.js';
const sseClients = new Set();
const requests = [];
export function registerSse(req, res, initialStatus = {}) {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Cache-Control', 'no-transform');
res.setHeader('Connection', 'keep-alive');
// Disable proxy buffering in Nginx
res.setHeader('X-Accel-Buffering', 'no');
res.flushHeaders?.();
res.write(`event: hello\n`);
res.write(`data: {"ok":true}\n\n`);
if (initialStatus && Object.keys(initialStatus).length) {
res.write(`event: status\n`);
res.write(`data: ${JSON.stringify(initialStatus)}\n\n`);
}
sseClients.add(res);
// Heartbeat to keep proxies/load balancers from timing out idle SSE
// Send a comment line every 20s
const hb = setInterval(() => {
try { res.write(`: ping\n\n`); } catch { /* ignore */ }
}, 20000);
req.on('close', () => {
clearInterval(hb);
sseClients.delete(res);
});
}
export function pushRequest(rec) {
requests.push(rec);
while (requests.length > MAX_REQUESTS) requests.shift();
const payload = `data: ${JSON.stringify(rec)}\n\n`;
for (const res of sseClients) {
try { res.write(payload); } catch { /* ignore */ }
}
}
export function broadcastStatus(payload) {
const ev = `event: status\n` + `data: ${JSON.stringify(payload)}\n\n`;
for (const res of sseClients) {
try { res.write(ev); } catch { /* ignore */ }
}
}
export function clearRequests() {
requests.length = 0;
const payload = `event: clear\n` + `data: {"ok":true}\n\n`;
for (const res of sseClients) {
try { res.write(payload); } catch { /* ignore */ }
}
}
export function getRecentRequests() {
return requests.slice(-MAX_REQUESTS);
}