【问题标题】:How to ensure that clients are ready before emitting from socket.io server如何确保客户端在从 socket.io 服务器发出之前准备好
【发布时间】:2016-06-19 05:37:10
【问题描述】:

我正在尝试使用 socket.io 制作一个两人竞争的迷宫游戏。为了确保两个玩家获得相同的迷宫,我想向两个客户端发送一个种子,然后客户端根据所述种子生成一个迷宫。然而,当第二个玩家加入时,只有第一个玩家(已经在房间里)接收到发射。

这里是相关的服务器端房间和种子发射代码:

// Find and join an unfilled room
var roomID = 0;
while (typeof io.sockets.adapter.rooms[roomID.toString()] !== 'undefined' && io.sockets.adapter.rooms[roomID.toString()].length >= 2)
    roomID++;
socket.join(roomID.toString());
console.log('A user from ' + socket.conn.remoteAddress + ' has connected to room ' + roomID);

// Seed announcement
if (io.sockets.adapter.rooms[roomID.toString()].length == 2) {
    var seed = Math.random().toString();
    socket.in(roomID).emit('seed', seed);
    console.log("announcing seed " + seed + " to room " + roomID);
}

socket.on('seedAck', function(msg) {
    console.log(msg);
})

在客户端,我有一些代码用种子响应服务器,以确定他们是否正确接收了种子。

socket.on('seed', function(msg) {
    // Some other code here...
    socket.emit('seedAck', 'client has recieved seed ' + msg);
});

这是服务器看到的内容:

A user from ::1 has connected to room 0
A user from ::1 has connected to room 0
announcing seed 0.936373041709885 to room 0
client has received seed 0.936373041709885

为了验证只有已经在房间里的客户端收到了种子,我刷新了第一个客户端,这次只有第二个客户端收到了种子。

我相信发生的事情是服务器在第二个客户端准备好之前发送种子。然而,经过多次谷歌搜索,我无法找到解决方案。我正在考虑向客户端添加一个按钮,要求用户首先按下按钮(从而确保客户端已准备好),但随后需要进行一些繁琐的簿记。我也在考虑某种回调函数,但我还没有得出关于如何正确实现它的结论。

我唯一的选择是在两个客户端都准备好时手动跟踪,还是有更好的解决方案集成在 socket.io 中?

编辑:我尝试修改我的代码,以便在发送种子之前等待两个客户端发送准备就绪的消息。服务器端,我有这个:

socket.on('ready', function(msg) {
    console.log(msg);
    // Seed announcement
    if (io.sockets.adapter.rooms[roomID.toString()].length == 2) {
        var seed = Math.random().toString();
        socket.to(roomID).emit('seed', seed);
        console.log("announcing seed " + seed + " to room " + roomID);
    }
});

在客户端,我现在有这个:

socket.on('seed', function(msg) {
    // Some other code here ...
    socket.emit('seedAck', 'client has received seed ' + msg);
});

socket.on('connect', function() {
    socket.emit('ready', 'client is ready!');
});

但是,同样的问题仍然存在,如服务器输出所示:

A user from ::1 has connected to room 0
client is ready!
A user from ::1 has connected to room 0
client is ready!
announcing seed 0.48290129541419446 to room 0
client has received seed 0.48290129541419446

第二个客户端仍然没有正确接收种子。

【问题讨论】:

  • 你是否从同一个浏览器连接到服务器两次?
  • 对于开发,是的。我现在在从外部访问服务器时遇到了一点问题,但这是另一个不应该影响这一点的单独问题。
  • 尝试从 2 个不同的浏览器连接,一旦有帮助,我遇到了同样的问题。
  • 尝试通过 IE 11 和 Chrome 51 连接。无论第一次连接的顺序如何,第二个客户端仍然无法正确接收种子。不过,感谢您的建议!

标签: socket.io


【解决方案1】:

对我已编辑的服务器代码的小修改解决了该问题:

socket.on('ready', function(msg) {
    console.log(msg);
    // Seed announcement
    if (io.sockets.adapter.rooms[roomID.toString()].length == 2) {
        var seed = Math.random().toString();
        io.sockets.in(roomID.toString()).emit('seed', seed); // Modified line
        console.log("announcing seed " + seed + " to room " + roomID);
    }
});

此解决方案取自this SO question

【讨论】:

    猜你喜欢
    • 2019-05-09
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 2019-03-15
    相关资源
    最近更新 更多