简体   繁体   中英

strange thing with timing logic using socket.io, jquery mobile, socket.emit();

I'm working on cordova with node.js socket.io. I found very strange thing happening with socket.emit();

The code below fails, although codings are correct , to enter 'room'

client-side jsfile.js

//Two global variables which are going to be used for socket connection
var deviceUuid ="";
var socket ="";

$(document).on('pageinit', '#mainPage', function(){
    document.addEventListener('deviceready', onDeviceReady, false);
});

function onDeviceReady(){
   //prepare serverUrl to connect socket to
   var serverUrl = "http://xxxx:9000";

   //prepare device Uuid to send to socket server
   devceUuid = device.uuid; //should be successful because it's called after the device is ready

   //connect socket to the server 
   socket = io.connect(serverUrl);

   //my socket is connected to the server, so I am going to enter the 'room'
   //Here, I am sending with me the deviceUuid variable.
   socket.emit('enterRoom', deviceUuid);
}

server-side Node.js

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

var server = http.createServer(function (request, response){
       console.log('server created');
}).listen(9000, function(){
       console.log('server running!');
});

//server is ready and it is listening to any incoming client sockets.
var io = socketio.listen(server);

io.sockets.on('connection', function (socket){
    console.log('client entered');  // <------ this shows up in console

    socket.on('enterRoom', function (deviceUuid){
            console.log('client entered a room: ', deviceUuid); <----This doesn't show up in console.
            socket.join("roomname");
    });
 });

Since I kept failing to enter room, I thought maybe

socket.emit('enterRoom', deviceUuid); 

is being called too fast that either the variable 'socket' or 'deviceUuid' isn't ready. So I used loops to make sure both of the two variables are set before doing socket.emit();

client-side jsfile.js with LOOP

//Two global variables which are going to be used for socket connection
var deviceUuid ="";
var socket ="";

$(document).on('pageinit', '#mainPage', function(){
    document.addEventListener('deviceready', onDeviceReady, false);
});

function onDeviceReady(){
   //prepare serverUrl to connect socket to
   var serverUrl = "http://xxxx:9000";

  //make sure deviceUuid and socket are both set before moving on.
  while(deviceUuid=="" || socket==""){
     deviceUuid = device.uuid;
     socket = io.connect(serverUrl);

     //When both deviceUuid and socket are set, do enter 'room'
     if(deviceUuid!="" && socket!=""){
       socket.emit('enterRoom', deviceUuid);
     } //if ends
  } // while ends
} // onDeviceReady() ends

This failed as well until.. I put alert(deviceUuid); at the end of my jsfile.js like this:

working client-side jsfile.js

var deviceUuid ="";
var socket ="";
$(document).on('pageinit', '#mainPage', function(){
    document.addEventListener('deviceready', onDeviceReady, false);
});

function onDeviceReady(){
   //prepare serverUrl to connect socket to
   var serverUrl = "http://xxxx:9000";

   //prepare device Uuid to send to socket server
   devceUuid = device.uuid; //should be successful because it's called after the device is ready

   //connect socket to the server 
   socket = io.connect(serverUrl);

   //my socket is connected to the server, so I am going to enter the 'room'
   //Here, I am sending with me the deviceUuid variable.
   socket.emit('enterRoom', deviceUuid);

   /*--------- this one line of code is the only added line--------*/
   alert(deviceUuid);
}

Now with alert(deviceUuid); , I now can enter 'room' with no problem. Can anyone explain what is causing this?

Just use socket = io.connect() , nothing more. No need to pass a server URL or anything else. I never passed anything as argument and it's working perfectly well.

Your presumption is right, socket is not ready by the time the emit is called. You can use the connect event to check when the connection is ready and run a function.

socket.on('connect', function(){
   socket.emit('enterRoom', deviceUuid);
});

The reason it works with the alert is because alert halts JS execution until the user clicks OK.

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