sseManager.js (1423B)
1 const { MAX_CONNECTIONS_PER_TOKEN } = require('./config'); 2 3 // --- SSE CONNECTION MANAGER --- 4 const activeConnections = []; 5 const clients = { 6 chats: new Set(), 7 messages: new Map(), 8 sync: new Set() // Global message-sync clients (one connection covers all chats) 9 }; 10 11 function enforceConnectionCeiling(req, res, cleanupFunction) { 12 const token = req.query.token || req.headers.authorization?.split(' ')[1]; 13 activeConnections.push({ res, token, cleanup: cleanupFunction }); 14 15 const userConns = activeConnections.filter(c => c.token === token); 16 if (userConns.length > MAX_CONNECTIONS_PER_TOKEN) { 17 const oldestIdx = activeConnections.findIndex(c => c.token === token); 18 if (oldestIdx > -1) { 19 const oldest = activeConnections[oldestIdx]; 20 oldest.cleanup(); 21 oldest.res.end(); 22 activeConnections.splice(oldestIdx, 1); 23 } 24 } 25 26 res.on('close', () => { 27 const idx = activeConnections.findIndex(c => c.res === res); 28 if (idx > -1) activeConnections.splice(idx, 1); 29 cleanupFunction(); 30 }); 31 } 32 33 function startHeartbeat() { 34 // Global heartbeat to keep Render connections alive 35 setInterval(() => { 36 activeConnections.forEach(({ res }) => { 37 try { res.write(': ping\n\n'); } catch (e) {} 38 }); 39 }, 25000); 40 } 41 42 module.exports = { clients, enforceConnectionCeiling, startHeartbeat };