基于HTML、Node.js的聊天应用:Socket加载历史消息时其他用户收到重复内容的问题
解决聊天应用刷新页面时其他用户收到重复历史消息的问题
我一眼就看出问题出在哪啦!你当前的代码在用户连接(connect事件触发)时,用ctx.io.emit('message', ...)给所有在线客户端广播历史消息,这就导致当已有用户在线时,只要有人刷新页面触发连接事件,其他用户就会重复收到一遍历史消息。
核心问题分析
ctx.io.emit() 是向所有连接的socket客户端发送消息,而我们只需要把历史消息发给刚连接的那个用户就够了,应该用ctx.socket.emit()来针对单个客户端发送。
修复后的代码
let msgArray = [] const updateCounter2 = ctx => { // 给所有用户更新在线人数,这部分逻辑没问题 ctx.io.emit('count', Object.keys(ctx.io.sockets.sockets).length); // 只给当前刚连接的用户发送历史消息,而非全体用户 msgArray.forEach(msg => { ctx.socket.emit('message', msg); }); }; server([ get('/', ctx => render('msg.hbs')), socket('connect', updateCounter2), socket('message', ctx => { console.log(ctx.data); // 新消息依然广播给所有用户,正常聊天不受影响 ctx.io.emit('message', ctx.data); msgArray.push(ctx.data) }) ]);
关键修改点
- 把循环里的
ctx.io.emit改成ctx.socket.emit,确保历史消息只推送给刚完成连接的用户,不会打扰其他在线用户 - 把
for (var i in msgArray)换成msgArray.forEach,避免遍历到数组原型上的额外属性,是更安全的数组遍历方式
这样修改后,不管是新用户加入还是老用户刷新页面,都只有当前操作的用户会加载历史消息,其他在线用户不会收到重复内容,完全符合你的需求~
内容的提问来源于stack exchange,提问作者moie
相关产品推荐
相关产品推荐

