javascript - socket.io 在每个新客户端连接时都会复制信息

标签 javascript node.js mongodb sockets socket.io

我是 Node.js 和 socket.io 的新手。我创建了一个小应用程序,其想法是当通过 websocket 激活函数(函数运行“emit”)时,该表会从 socket.io 实时显示。 问题是,每次我打开一个新客户端时,信息都会重复每个客户端,如果我打开两个客户端,然后更新其中一个,然后以前的重复信息,我该如何修复它?

谢谢!

这是服务器中的代码:

// socket.io
var http = require('http').Server(app);
var io = require('socket.io')(http);


// winner
function bitcoin_winner_socket(){
   bitcoin_winners.find().limit(50).exec(function (err, response) {
   console.log(response);
   io.sockets.emit('bitcoin_winners', JSON.stringify(response));  
});
}

// veasy
function bitcoin_veasy_socket(){
   bitcoin_veasy.find().exec(function (err, response) {
   console.log(response);
   io.sockets.emit('bitcoin_veasy', JSON.stringify(response));  
});
}


io.on('connection', function(socket){
   console.log('user connected');

   bitcoin_winner_socket();
   bitcoin_veasy_socket();

});


http.listen(3001, function(){
   console.log('listening on *:3001');
});
// socket.io

这是客户端代码:

<script>

var socket = io();

socket.on('bitcoin_winners', function(response){
    $('#abc').text(response);
});

socket.on('bitcoin_veasy', function(response){

$.each(JSON.parse(response), function(index, value){
    $("#tabla-veasy").append("<tr><td>" + (parseInt(index+1)) + "</td>    <td>" + value.senders + "</td><td>" + value.amount_received + "</td><td><a href='https://chain.so/tx/BTCTEST/"+value.txid+"'>"+value.txid+"</a></td></tr>");
});

});

</script>

最佳答案

让我们跟踪每次套接字连接到服务器时会发生什么。

  1. 在服务器上的 connection 事件中(当套接字连接时),您将调用两个函数“bitcoin_winner_socket()bitcoin_veasy_socket().
  2. bitcoin_winner_socket() 看起来它会在数据库中查找获奖者,然后将该获奖者列表发送到所有现有套接字。
  3. 当每个客户端收到获奖者列表时,客户端会在包含获奖者列表的页面中设置 #abc 项。虽然这对于每个客户端来说可能是不必要的工作,只是因为有一个新的套接字连接,但这不会导致任何问题。
  4. bitcoin_veasy_socket() 看起来它会执行某种其他数据库搜索,然后将响应发送到所有连接的客户端。
  5. 问题出现在客户端,因为当客户端收到'bitcoin_veasy'消息时,它将所有这些信息附加到现有表中(而不是替换它)。这就是导致重复信息的原因。连接新的套接字后,您会将'bitcoin_veasy'信息的全新副本附加到所有连接的客户端。

一个简单的修复方法是更改​​您的'bitcoin_veasy'消息处理以替换现有信息,而不是附加它。然后,您将永远不会得到重复项。

一种更完整的解决方案是仅在信息实际发生变化时才向客户端传输新信息,而不是每次有新连接时都向所有已连接的客户端发送数据。

从您的问题中我不明白何时需要将此信息发送到连接的客户端。您可以更改此信息的发送方式,仅将其发送到新连接的套接字,而不是将其发送到所有套接字。

您可以通过将新连接的 socket 传递给 bitcoin_winner_socket()bitcoin_veasy_socket() 函数来实现此目的,以便它们可以执行 socket.emit() 到单个套接字,而不是 io.sockets.emit() 到所有连接的套接字。

关于javascript - socket.io 在每个新客户端连接时都会复制信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30787731/

相关文章:

javascript - 如何在 React 上正确地将 onclick 处理程序绑定(bind)到 `this`

javascript - javascript 文件中的 Angular 分割 json

javascript - PHP - 如何将 RGB 颜色转换为 CIE 1931 颜色规范

node.js - 使用 json post 进行摘要身份验证的 Curl 命令

node.js - 如何使用reactjs将导入的csv数据显示到表格中?

javascript - 如何创建包含对象和数组的MongoDB文档,以及Mongoose中相应的方案?

MongoDB在聚合查询中获取第一个和最后一个文档

javascript - 如何根据条件设置 Mongoose 模式的默认属性值

javascript - 简单 JSON 对象未在 Javascript 中求值

javascript - bcrypt.js 比较方法如何知道加盐轮数?