Files
sse-server/lib/clients.js
2025-07-01 20:07:24 +08:00

75 lines
2.1 KiB
JavaScript

/**
* @file 管理所有 SSE 客户端连接的模块
* @author Yk <yk_9001@icloud.com>
* @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();