diff --git a/node-api/src/sse.js b/node-api/src/sse.js index 225b864..8822a45 100644 --- a/node-api/src/sse.js +++ b/node-api/src/sse.js @@ -6,7 +6,10 @@ 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`); @@ -15,7 +18,15 @@ export function registerSse(req, res, initialStatus = {}) { res.write(`data: ${JSON.stringify(initialStatus)}\n\n`); } sseClients.add(res); - req.on('close', () => sseClients.delete(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) { @@ -45,4 +56,3 @@ export function clearRequests() { export function getRecentRequests() { return requests.slice(-MAX_REQUESTS); } -