Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Nodejs, clients not always receiving server messages

Nodejs, clients not always receiving server messages

Problem

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:///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});
    });
Problem courtesy of: Hermann Ingjaldsson

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

});
Solution courtesy of: Emanuel Ralha

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

Nodejs, clients not always receiving server messages

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×