/** * @file 管理所有 SSE 客户端连接的模块 * @author Yk * @date 2025-07-01 * @description 提供客户端连接的添加、移除、获取及广播消息功能 */ class SSEClientsManager { /** * 构造函数,初始化一个 Map 来存储客户端连接 */ constructor() { this.clients = new Map(); // 使用 Map 存储 clientId 到响应对象的映射 } /** * 添加一个新的客户端连接 * @param {string} clientId - 客户端唯一标识 * @param {Object} res - HTTP 响应对象,用于后续通信 * @returns {number} 当前客户端数量 */ add(clientId, res) { this.clients.set(clientId, res); return this.clients.size; } /** * 移除指定的客户端连接 * @param {string} clientId - 要移除的客户端 ID * @returns {number} 移除后剩余的客户端数量 */ remove(clientId) { this.clients.delete(clientId); return this.clients.size; } /** * 获取指定的客户端响应对象 * @param {string} clientId - 客户端 ID * @returns {Object} 对应的响应对象,或 undefined */ get(clientId) { return this.clients.get(clientId); } /** * 向所有客户端广播数据 * @param {*} data - 要广播的数据,将被序列化为 JSON * @returns {number} 成功发送的客户端数量 */ broadcast(data) { let successCount = 0; for (const [id, res] of this.clients.entries()) { try { res.write(`data: ${JSON.stringify(data)}\n\n`); // 发送标准的 SSE 格式数据 successCount++; } catch (err) { this.remove(id); // 如果发送失败,移除该客户端连接 } } return successCount; } /** * 获取当前连接的客户端总数 * @returns {number} */ size() { return this.clients.size; } } // 导出单例实例,确保全局共享同一组客户端连接 module.exports = new SSEClientsManager();