简体   繁体   中英

socket.io functions not working in callbacks

The issue I am having is that I want the current session to join a room if they pass a database check. If they do pass the check, meaning the query returns a result, it should add the user to a room. However, when I call socket.join("room"), it does not work if its in the database callback function. Here is a SIMPLIFIED version of my code:

var pg = require('pg');
var conString = 'connection_to_postgres_server'

var server = require('http').createServer();
var io = require('socket.io')(server);
var port = 8080;


function defaultOnSuccess(query, result){
  console.log("Result of query `", query, "` -> ", result);
}
function defaultOnError(query, err){
  console.log("Error of query `", query, "` -> ", err);
}
function runQuery(query, queryParams, onSuccess, onError){
  onSuccess = (typeof onSuccess !== 'undefined' ? onSuccess : defaultOnSuccess);
  onError = (typeof onError !== 'undefined' ? onError : defaultOnError);
  pg.connect(conString, function(err, client, done){
    if(err){
      onError(query, err);
      done();
      return;
    }
    client.query(query, queryParams, function(err, result){
      if(err){
        onError(query, err);
        done();
        return;
      }
      else {
        onSuccess(query, result);
        done();
        return;
      }
    });
  });
}
function listenOn(channel, onNotification, onError){
  onError = (typeof onError !== 'undefined' ? onError : defaultOnError);
  pg.connect(conString, function(err, client, done){
    if(err){
      onError(channel, err);
      done();
      return;
    }
    client.on('notification', function(msg) {
      onNotification(channel, msg);
    });
    var query = client.query("LISTEN \"" + channel + "\";");
    done();
  });
}

io.on('connection', function(socket){
  runQuery("THIS QUERY SHOULD RETURN EXACTLY ONE RESULT IF THE USER IS VALIDATED", [], 
    function(query, result){
      if(result.rowCount == 1){

        console.log("Pre rooms: ", socket.rooms);
        socket.join("hello");
        console.log("Current rooms: ", socket.rooms);
      }
    }
  );
});

io.on('connection', function(socket){
  socket.on('disconnect', function(){
  });
});

server.listen(port, function(){
  console.log('listening on *:' + port);
  listenOn("project_tc_changed", 
    function(channel, message){
      console.log(message);
      io.emit("data", message);
    }
  );
});

When I connect with a client, the output of the "Pre rooms:" and "Current rooms:" log is exactly the same. In addition, the io.emit() in server.listen does not work, even though I know the code is getting called, because the message gets logged.

I know for a fact that the socket.join() call and the io.emit() call are getting reached, they are just not having any effects, and not returning any errors.

The socket.join is working as expected, but due to the asynchronous nature of javascript your console logs are not showing what you expected. In javascript every line of code is ran asynchronously, including your socket.join and console.log. This is why we have to make use of callbacks to see what the environment looks like after a function has completed. socket.join allows for this callback. So to see the room join in action, we simply have to change our 3 lines of code to the following:

    console.log("Pre rooms: ", socket.rooms);
    socket.join("hello", function(){
      console.log("Current rooms: ", socket.rooms);
    );

As for your emit; If you believe your emit is being reached and the message variable contains data, your io.emit should work. So without seeing what the client side code looks like it is hard to help solve for this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM