Socket.io如何向除指定ID列表外的所有连接客户端广播消息
需求实现方案
该需求完全可实现,针对Node.js生态最常用的两种Socket技术栈,具体实现方式如下:
Socket.IO 场景实现
方案1:Socket.IO v4+ 极简实现(推荐)
v4及以上版本内置了except方法,直接传入排除ID数组即可实现批量过滤,一行代码即可完成:
// 要排除的客户端ID数组 const excludeClientIds = ['xxx_id_1', 'xxx_id_2', 'xxx_id_3']; // 向排除列表外的所有客户端推送事件 io.except(excludeClientIds).emit('自定义事件名', { 消息内容字段: '对应值' });
方案2:全版本兼容遍历实现
如果用的是v3及以下版本,没有内置except方法,可以自行遍历所有在线客户端过滤后发送:
// 要排除的客户端ID数组 const excludeClientIds = ['xxx_id_1', 'xxx_id_2', 'xxx_id_3']; // 获取所有在线客户端的ID集合 const allOnlineSocketIds = await io.allSockets(); for (const socketId of allOnlineSocketIds) { // 过滤掉排除列表内的ID if (!excludeClientIds.includes(socketId)) { io.to(socketId).emit('自定义事件名', { 消息内容字段: '对应值' }); } }
如果是Socket.IO v2版本,获取所有在线客户端的代码调整为:
const allOnlineSocketIds = Object.keys(io.sockets.sockets);
原生WebSocket(ws库)场景实现
如果使用原生ws库,你需要自行维护客户端ID和连接实例的映射关系,过滤后发送即可:
// 自行维护的客户端映射:key为自定义客户端ID,value为ws连接实例 const clientMap = new Map(); // 要排除的客户端ID数组 const excludeClientIds = ['xxx_id_1', 'xxx_id_2', 'xxx_id_3']; for (const [clientId, wsConn] of clientMap.entries()) { // 过滤排除ID + 校验连接处于打开状态 if (!excludeClientIds.includes(clientId) && wsConn.readyState === WebSocket.OPEN) { wsConn.send(JSON.stringify({ event: '自定义事件名', data: { 消息内容字段: '对应值' } })); } }
注意事项
- 发送消息前建议校验连接状态,避免向已断开的连接推送抛出异常
- 如果你使用的是自定义客户端ID而非Socket.IO默认生成的socket id,需要自行维护自定义ID和连接实例的映射关系,再做过滤逻辑
内容的提问来源于stack exchange,提问作者dagoo
相关产品推荐
相关产品推荐

