Node.js中Socket.io如何通过自定义添加的userID字段获取对应socket实例
Socket.io通过自定义userID获取对应socket实例的实现方法
方案1:维护全局userID-socket映射表(推荐)
该方案查找效率为O(1),性能最优,适合绝大多数业务场景。你只需要额外维护一个存储userID和socket对应关系的对象/Map即可,记得在用户断开连接时清理对应数据避免内存泄漏。
- 初始化全局映射存储
// 单端登录场景用对象存储即可,多端登录可将值改为数组存储同一用户的多个socket实例 const userSocketMap = {};
- 登录事件中写入映射
socket.on('login',(userID)=>{ socket.userID = userID; // 写入映射表 userSocketMap[userID] = socket; })
- 断开连接时清理映射
socket.on('disconnect', () => { if(socket.userID && userSocketMap[socket.userID]?.id === socket.id) { delete userSocketMap[socket.userID]; } })
- 直接通过userID获取实例
const targetSocket = userSocketMap[目标userID];
方案2:遍历已连接socket实例查询(适配低频使用场景)
如果不想额外维护映射表,且查询频率很低、在线用户规模小,可以直接遍历所有已连接的socket匹配userID,缺点是查找效率为O(n),用户量大时性能差。
Socket.io 3.x及更早版本写法
function getSocketByUserId(userID) { for (const socketId in io.sockets.connected) { const currentSocket = io.sockets.connected[socketId]; if(currentSocket.userID === userID) { return currentSocket; } } return undefined; }
Socket.io 4.x版本写法
function getSocketByUserId(userID) { // io.sockets.sockets在4.x版本中为Map结构 for (const [socketId, currentSocket] of io.sockets.sockets) { if(currentSocket.userID === userID) { return currentSocket; } } return undefined; }
内容的提问来源于stack exchange,提问作者thilina aluthge
相关产品推荐
相关产品推荐

