import pg from 'pg'; export function registerSse(app) { const sseClients = []; app.get('/events', (req, res) => { res.set({ 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'X-Accel-Buffering': 'no' // 👈 desactiva el buffering en Nginx }); res.flushHeaders(); // Primer “hola” res.write('event: connected\ndata: {}\n\n'); // 🔴 Mantén viva la conexión con pings cada 15 s const keepAlive = setInterval(() => { res.write(':\n\n'); // comentario SSE = ping }, 15000); sseClients.push(res); console.log('🟢 Cliente SSE conectado (%d)', sseClients.length); req.on('close', () => { clearInterval(keepAlive); // limpia el intervalo sseClients.splice(sseClients.indexOf(res), 1); console.log('🔌 Cliente SSE desconectado (%d)', sseClients.length); }); }); const broadcast = (data) => { const payload = `data: ${data}\n\n`; sseClients.forEach((client) => client.write(payload)); }; const { Client: PgClient } = pg; const pgClient = new PgClient({ connectionString: process.env.DATABASE_URL }); pgClient.connect() .then(() => pgClient.query('LISTEN sse_events')) .then(() => console.log('🛎️ Listening to Postgres channel sse_events')) .catch((err) => console.error('PG listen error', err)); pgClient.on('notification', (msg) => { console.log('Notificación Postgres:', msg.payload); broadcast(msg.payload); }); }