Nest.js WebSocket中Set无法添加字符串问题排查求助
已知代码在沙箱环境正常,但目标环境出现user.openViews.add('messages')无效果的问题,且已确认user能正常获取,可能的原因如下:
openViews未正确初始化为Set实例
虽然activeUsers的类型定义中openViews标注为Set<string>,但实际向activeUsers添加用户数据时,可能误将openViews初始化为数组([])或undefined。比如:// 错误示例:用数组代替Set this.activeUsers.set(userId, { socketId: client.id, openViews: [] });数组没有
add方法,调用user.openViews.add('messages')不会报错但也不会生效,而沙箱环境可能正确使用了new Set()初始化,所以表现正常。多实例部署下的内存隔离问题
如果你的Nest.js应用是多实例部署(比如PM2集群模式、K8s多Pod),每个实例的activeUsers是内存独立的Map。若用户WebSocket连接建立在实例A,但message:opened消息被路由到实例B,那么实例B的activeUsers中该用户的openViews可能未被正确初始化,或是独立的Set实例,导致添加操作无法反映到用户实际连接的实例中。其他代码对openViews的意外修改
检查项目中是否有其他地方修改了user.openViews的引用,比如在某个函数中重新赋值:// 意外覆盖了Set引用 user.openViews = new Set(['profile']);或者将
openViews转换为数组后未重新赋值回Set,导致后续的add操作作用在无效的引用上。竞态条件导致的时序问题
如果添加用户到activeUsers的操作是异步的(比如依赖数据库查询结果),而handleMessageOpened在用户数据完全初始化前就被触发,此时虽然user存在,但openViews可能还未被正确初始化(比如仍是undefined),后续的add操作自然无效。
内容的提问来源于stack exchange,提问作者Simon

