87 lines
2.4 KiB
JavaScript
87 lines
2.4 KiB
JavaScript
'use strict'
|
|
|
|
/**
|
|
* services/sse.js — Gerenciamento centralizado de Server-Sent Events
|
|
*
|
|
* sseClients: Map<accountId (string), { res, tenantId }>
|
|
*
|
|
* Funções exportadas:
|
|
* register(accountId, tenantId, res) — registra cliente
|
|
* unregister(accountId) — remove cliente
|
|
* sseSend(accountId, event, data) — envia para um cliente específico
|
|
* sseBroadcast(event, data) — envia para TODOS os clientes
|
|
* sseBroadcastTenant(tenantId, event, data, excludeAccountId?)
|
|
* — envia para todos do mesmo tenant
|
|
* isOnline(accountId) — verifica se cliente está conectado
|
|
* onlineIds(tenantId) — lista de accountIds online em um tenant
|
|
*/
|
|
|
|
const sseClients = new Map() // String(accountId) → { res, tenantId }
|
|
|
|
function register(accountId, tenantId, res) {
|
|
sseClients.set(String(accountId), { res, tenantId: String(tenantId) })
|
|
}
|
|
|
|
function unregister(accountId) {
|
|
sseClients.delete(String(accountId))
|
|
}
|
|
|
|
function sseSend(accountId, event, data) {
|
|
const client = sseClients.get(String(accountId))
|
|
if (!client) return false
|
|
try {
|
|
client.res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`)
|
|
return true
|
|
} catch {
|
|
sseClients.delete(String(accountId))
|
|
return false
|
|
}
|
|
}
|
|
|
|
function sseBroadcast(event, data) {
|
|
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`
|
|
sseClients.forEach((client, id) => {
|
|
try { client.res.write(payload) } catch { sseClients.delete(id) }
|
|
})
|
|
}
|
|
|
|
function sseBroadcastTenant(tenantId, event, data, excludeAccountId = null) {
|
|
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`
|
|
const tid = String(tenantId)
|
|
const excl = excludeAccountId ? String(excludeAccountId) : null
|
|
sseClients.forEach((client, id) => {
|
|
if (client.tenantId === tid && id !== excl) {
|
|
try { client.res.write(payload) } catch { sseClients.delete(id) }
|
|
}
|
|
})
|
|
}
|
|
|
|
function isOnline(accountId) {
|
|
return sseClients.has(String(accountId))
|
|
}
|
|
|
|
function onlineIds(tenantId) {
|
|
const tid = String(tenantId)
|
|
const ids = []
|
|
sseClients.forEach((client, id) => {
|
|
if (client.tenantId === tid) ids.push(Number(id))
|
|
})
|
|
return ids
|
|
}
|
|
|
|
function connectedCount() {
|
|
return sseClients.size
|
|
}
|
|
|
|
module.exports = {
|
|
sseClients,
|
|
register,
|
|
unregister,
|
|
sseSend,
|
|
sseBroadcast,
|
|
sseBroadcastTenant,
|
|
isOnline,
|
|
onlineIds,
|
|
connectedCount,
|
|
}
|