重新连接SocketIO后重新加入同一个房间的问题

时间:2016-04-25 02:43:11

标签: node.js socket.io

我试图理解为什么下面的代码由于某种原因不起作用。基本上我希望同一个客户端能够重新加入同一个房间,但不知何故,当我在该客户端重新连接后打印该房间的客户列表时,只有这个客户端出现,休息时间不存在?

客户端

var id=null, socket = null;
var publicKey = null;
var first = Math.random().toString(36).substring(2,8);
var last = Math.random().toString(36).substring(2,8);
$('#bt1').click(function(){
    socket = io();
    socket.on('connect',function(){
        addText('Connect to server. First-Last '+ first +' '+last);
    });
    socket.on('disconnect',function(data){          
        addText('Disconnect from server'); 
    });
    socket.on('verifyid_1',function(data){
        id = data.id;
        socket.emit('verifyid_2',{id:id,publicKey:publicKey})
        addText('ClientID '+id); 
    });
    socket.on('gamecreated',function(data){
        publicKey = data.publicKey;
        addText('PublicKey '+publicKey);
    });
    socket.on('playerrejoinroom',function(data){addText(JSON.stringify(data))});
});
$('#bt2').click(function(){ socket.connect();});
$('#bt3').click(function(){ socket.disconnect();});
$('#bt4').click(function(){
    publicKey = $('#input').val(); addText('PublicKey '+publicKey+' is entered');
    socket.emit('joinroom',{publicKey:publicKey});
});
$('#bt5').click(function(){
    addText('Create new game with clientID '+id);
    socket.emit('creategame',{id:id,NumberOfPlayers:5,UserInfo:{first:first,last:last}});
});
function addText(text){ // this juts logs to a chatbox on screen
    $('#messages').append($('<li>').text(text)); 
    $('#console').scrollTop($('#console').prop("scrollHeight"));
}

服务器

io.on('connection', function(socket){
    var id = socket.id;
    var publicKey = null;
    console.log('a user connected with id '+id);
    socket.emit('verifyid_1',{id:id});

    socket.on('verifyid_2',function(data){    
        if (id != data.id) {console.log('___Old client reconnects '+data.id);}
        console.log('___Double check '+id);
        if (util.isExists(data.publicKey)) { // this function just check if the obj exists or not
            socket.join(publicKey); // if publickey exists, this socket should join the previous room identified by publicKey
            listClientsInRoom(publicKey);
        }
    });
    socket.on('disconnect', function(){
        console.log('user#'+id+' disconnected '+util.isExists(io.sockets.adapter.rooms[publicKey]));    
        if (!util.isExists(io.sockets.adapter.rooms[publicKey])) return;
        listClientsInRoom(publicKey);
    });
    socket.on('creategame',function(data){
        var owner = {id:data.id, first:data.UserInfo.first, last:data.UserInfo.last};
        var newpublicKey = controller.addGameSession(data.NumberOfPlayers,owner); 
        socket.join(newpublicKey); 
        publicKey = newpublicKey;
        socket.emit('gamecreated',{publicKey:publicKey});
    });

    socket.on('joinroom',function(data){
        console.log("Joinroom for client "+id+" to room: "+data.publicKey);
        socket.join(data.publicKey); publicKey = data.publicKey;
        listClientsInRoom(publicKey);      
    });
});
function listClientsInRoom(key){
  var clients = io.sockets.adapter.rooms[key].sockets;
  console.log('___Clients in room:'+JSON.stringify(clients));
}

当我使用3个客户端运行时,服务器上的输出:

a user connected with id /#mxZOL2Ibr9jrsMkiAAAA
___Double check /#mxZOL2Ibr9jrsMkiAAAA
a user connected with id /#oGt5s1ILXhp5tGy9AAAB
___Double check /#oGt5s1ILXhp5tGy9AAAB
a user connected with id /#59OZXN32hnBWzyDVAAAC
___Double check /#59OZXN32hnBWzyDVAAAC
Joinroom for client /#oGt5s1ILXhp5tGy9AAAB to room: m9xdowe7lxat088508
___Clients in room:{"/#mxZOL2Ibr9jrsMkiAAAA":true,"/#oGt5s1ILXhp5tGy9AAAB":true}
Joinroom for client /#59OZXN32hnBWzyDVAAAC to room: m9xdowe7lxat088508
___Clients in room:{"/#mxZOL2Ibr9jrsMkiAAAA":true,"/#oGt5s1ILXhp5tGy9AAAB":true,"/#59OZXN32hnBWzyDVAAAC":true}
user#/#59OZXN32hnBWzyDVAAAC disconnected true
___Clients in room:{"/#mxZOL2Ibr9jrsMkiAAAA":true,"/#oGt5s1ILXhp5tGy9AAAB":true}
a user connected with id /#m4k21oL_S493uVmpAAAD
___Double check /#m4k21oL_S493uVmpAAAD
___Clients in room:{"/#m4k21oL_S493uVmpAAAD":true}

发生了什么:

1. Connect 3 clients by hitting connect button (bt1).
2. Client1 create new game (button bt5). Save the publicKey locally.
3. Client2 and client3 use this publicKey to join the room (button bt4)
4. Client3 disconnect (button bt3).
5. Client3 reconnect (button bt2)
6. Only ID of client3 is shown in the room of publicKey ??? 

1 个答案:

答案 0 :(得分:1)

我相信重复问题和我的代码有助于我找到问题所在.......

if (util.isExists(data.publicKey)) { 
    socket.join(data.publicKey); // publicKey is a local variable to a newly established socke
        // so when the client reconnect this variable should be null by default.
        // I should have used data.publicKey given by the client instead. My bad
    listClientsInRoom(data.publicKey);
} 

对不起。它现在有效。