Search code examples
javascriptnode.jsclientbandwidth

Nodejs, clients not always receiving server messages


I am setting up a very basic node application, the plan is that anyone can go on the site and press a letter and that will increment a counter. Everybody can then see that counter going up as people all over the world are incrementing it. It works brilliantly, except that the way i set it up in the beginning then the node server is contacting each client 20 times per second, which is very wasteful.

So in order to avoid that i added a condition that the counter must have increased in order for the node server to send the message. But when I do that the messages never really make it to all the clients, how they go to the clients is some confusing, apparently random order.

This is my first node app and I am still getting the hang of it, can anybody point me in the right direction with this? The problem is probably in the increment_time function.

Server part:

var http=require('http');
var io=require('socket.io');
var fs=require('fs');

var sockFile=fs.readFileSync('text');
server=http.createServer();

//2. get request, via port, http://localhost:8000
server.on('request', function(req, res){
    console.log('request received');
    res.writeHead(200, {'content-type':'text/html'});
    res.end(sockFile);
    }); 

//have server and socket listen to port 8000.
server.listen(8000);
var socket=io.listen(server);

//the lower the number the less chatty the debug becomes.
socket.set('log level', 1); 

//initiate the counter.
counter=0;
counterp=0;


//3. on client connect.
//http://<address>/apps/press_k
socket.on('connection', function(socket){
    console.log("Client connected.");

    //increment counter on clients command.
    socket.on('s_increment_counter',function(data){
    counter++;
    console.log('New counter:'+counter);
    });

//send the counter to all clients if it has increased.
increment_time_continuously();
function increment_time(){
    //this is the condition that is to limit how often node sends to the clients,
    //but setting it on means the counter will be delivered in some erratic way 
    //to the  clients.
    //if(counter===counterp)  {return;}

    //send current counter to all clients.
    console.log("passed the equals, now broadcast.");
    //this part is clearly only sending to one of them.
    socket.emit('c_display_counter', counter);
    //client.broadcast.emit('c_display_counter', counter)
    //client.send('Welcome client');

    counterp=counter;
    }
function increment_time_continuously(){setInterval(increment_time,50);}
});

Relevant client part:

//client_to_server:
//-tell server to increment counter.
function s_increment_counter(){
    socket.emit('s_increment_counter',{counter:0});
    }

//server_to_client:
//-when server tells to display counter, display counter.
socket.on('c_display_counter',function(counter){
    //counter=data["counter"];
    k_counter_text.attr({"text":counter});
    });

Solution

  • The problem is that you dont store your connections and when you broadcast with socket.emit it goes only to your last connection, you need to store each connection (in a array or something) that has connected to the socket and then iterate over all your connections and broadcast the message you want.

    var http=require('http');
    var io=require('socket.io');
    var fs=require('fs');
    
    var sockFile=fs.readFileSync('text');
    server=http.createServer();
    
    //2. get request, via port, http://localhost:8000
    server.on('request', function(req, res){
        console.log('request received');
        res.writeHead(200, {'content-type':'text/html'});
        res.end(sockFile);
        }); 
    
    //have server and socket listen to port 8000.
    server.listen(8000);
    var socket=io.listen(server);
    
    //the lower the number the less chatty the debug becomes.
    socket.set('log level', 1); 
    
    //initiate the counter.
    counter=0;
    counterp=0;
    connections = {};
    
    
    
    
    function broadcastToConnections(){
      for(c in connections){
        var con = connections[c];
          con.emit('c_display_counter', counter);
      }
    }
    
    function connectionClose(socket){
      delete connections[socket.id];
    }
    
    
    //3. on client connect.
    //http://<address>/apps/press_k
    socket.on('connection', function(socket){
        console.log("Client connected.");
    
        //increment counter on clients command.
        socket.on('s_increment_counter',function(data){
          counter++;
          console.log('New counter:'+counter);
    
          broadcastToConnections();
        });
    
        connections[socket.id] = socket;//here we store our connection in connections obj
    
        socket.on('close', connectionClose);//we listen to close event to remove our connection from connection obj
    
    });