socket.io duplicates information every new client is connected

788 Views Asked by At

I am new to Node.js and socket.io. I created a small app, the idea is that the table is displayed in real time from socket.io when a function is activated through a websocket (function run a "emit"). The problem is that every time I open a new client the information duplicates every client, if I open two clients, and I update one of them then the previous duplicates information, how I can fix it?

Thanks!

this is the code in server:

// 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

and this is the client code:

<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

There are 1 best solutions below

2
On

Let's trace what happens each time a socket connects to your server.

  1. In the connection event on the server (when a socket connects), you're calling two functions" bitcoin_winner_socket() and bitcoin_veasy_socket().
  2. bitcoin_winner_socket() looks like it does a database lookup of winners and then sends that list of winners to all exist sockets.
  3. When each client receives the list of winners, the client set the #abc item in the page with the list of winners. While this is probably unnecessary work for every client to do just because a new socket connect, this doesn't cause any problems.
  4. bitcoin_veasy_socket() looks like it does some sort of other database search and then sends the response to all connected clients.
  5. The problem arises in the client because when the client receives the 'bitcoin_veasy' message, it appends all this information to an existing table (rather than replaces it). That is what is causing the duplicate information. Upon ever new socket connected, you're appending a whole new copy of the 'bitcoin_veasy' information to all connected clients.

A simple fix would be to change your 'bitcoin_veasy' message processing to replace the existing information, not append it. Then, you would never get duplicates.

A more complete solution would be to only transmit new information to clients when the information has actually changed, rather than sending data to all connected clients everytime a new one connects.

I don't understand from your question exactly when this information needs to be sent to a connected client. It is possible that you could change the sending of this information to only send it to the newly connected socket, rather than sending it to all sockets.

You would do that by passing the newly connected socket to your bitcoin_winner_socket() and bitcoin_veasy_socket() functions so they can do socket.emit() to a single socket rather than io.sockets.emit() to all connected sockets.