1

I am using socket.io, redis for tracking users online/offline status. Here I am storing the no.of users with name as key with the pattern hub_id. I am able to get the number of users by just getting count of keys matching hub_ pattern. Now the key has value as status online or offline.

I am unable to get the no. users online or offline variable outside the for loop.

  app.get('/test', function(req, res) {
  client.keys('hub*', function (err, keys) {
    console.log(keys.length);
    for (var i=0; i<keys.length; i++){
    client.hgetall(keys[i], function(err, reply) {
    if(reply.status == "online"){
      onlinehub++;
    }
    else if(reply.status == "offline"){
      offlinehub++;
    }
  });
  }
    console.log(onlinehub +"-" +offlinehub)

    });
});
  • Note that `HGETALL` blocks the server while it is running - if your Hash is big, this could take a while... Instead, what you should do, is keep counters (in Redis) of your offline/online/whatever users so you can get the reply with one read operation. – Itamar Haber Apr 10 '17 at 11:10

1 Answers1

0

Here you are not able to access the onlinehub and offlinehub outside for loop is because these variables are updated in async function call i.e

client.hgetall(keys[i], function(err, reply) { //<-- this is callback function
if(reply.status == "online"){
  onlinehub++;
}
else if(reply.status == "offline"){
  offlinehub++;
}
console.log(onlinehub +"-" +offlinehub); //Put the log here and check if it is giving correct numbers?
});

So you can only access updated values of onlinehub and offlinehub variable within that async callback function. Right now you must be getting 0-0 as log on your console.

To fix this you can look into the below code

app.get('/test', function(req, res) {
    //Defined a callback function to know when counting on redis keys finished
    var onComplete = function() {
       console.log(onlinehub+"-"+offlinehub);
    };
    client.keys('hub*', function (err, keys) {
        console.log(keys.length);
        var taskToGo = keys.length;
        if(taskToGo==0){
           onComplete();
       }else{
          for (var i=0; i<keys.length; i++){
              client.hgetall(keys[i], function(err, reply) {
                  if(reply.status == "online"){
                    onlinehub++;
                  }
                  else if(reply.status == "offline"){
                      offlinehub++;
                  }
                  //Added this line 
                  if(--taskToGo==0){ 
                     onComplete();
                  }
                });
          }
       }
    });
});

You can take help from async for loop in node.js

Community
  • 1
  • 1
Samarth
  • 773
  • 1
  • 6
  • 14