75 lines
2.1 KiB
JavaScript
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();
|