断开连接后Socket.io没有正确触发事件

时间:2014-03-02 01:01:06

标签: javascript node.js sockets websocket socket.io

所以我想用socket.io构建一个小游戏应用程序,它的工作原理如下:

用户加载网站,我使用generalConnection命名空间

创建一个通用套接字
app.generalSocket = io.connect('http://localhost/generalConnection');

我还没有任何特殊事件,但我认为将它与第二个命名空间分开会很好。

当用户登录时,我调用一个启动游戏连接的函数(另一个命名空间)并将一些事件绑定到它,我不会全部列出,我认为这并不重要。

app.startGameSocket = function() {
    app.gameSocket = io.connect('http://localhost/gameConnection'); //game connection

    app.gameSocket.on("connect", function() {
        console.log("connected to the game socket");
    });
}

在服务器端,我有类似的东西:

var connectedPlayers = [];
var gameConnection = io.of('/gameConnection').on('connection', function (socket) {
    socket.on('disconnect', function () {
        //some stuff
    });
});

再一次,我认为我不需要列出所有事件,我只会解释它是如何工作的。

它监听新玩家事件,创建新玩家,将其推送到connectedPlayers数组,然后将其发送给连接到gameConnection名称空间的所有人。

用户列表已更新,每个人都很高兴。我还可以在用户关闭浏览器窗口时监听其他事件,例如断开连接并适当更新connectedPlayers数组。

当用户从游戏中注销时,我还必须断开gameConnection命名空间,所以在客户端我做:

app.vent.on('logOut', function() {
    app.gameSocket.disconnect();
)};

请注意,我将generalConnection命名空间保持打开状态,我只是断开了gameConnection命名空间。

它很好用,如果用户注销或关闭窗口,在服务器端触发disconnect事件,connectedPlayers数组会更新并发送回连接的播放器。

问题

当用户:

  1. 进入网站。
  2. 登录游戏。
  3. 退出。
  4. 在没有刷新窗口的情况下再次登录(再次触发app.startGameSocket功能)。
  5. 在关闭窗口之后,不会在服务器上触发gameConnection命名空间断开事件,并且不会更新列表。
  6. 节点shell说的内容如下:info - 传输结束(套接字结束)但不触发disconnect事件。请帮助:)

    我试过

    app.vent.on('logOut', function() {
        app.gameSocket.emit('forceDisconnect'); //force disconnect on the server side
        app.gameSocket.disconnect();
        app.gameSocket.removeAllListeners(); //tried to really kill disconnected socket
    )};
    

    但没有结果。

3 个答案:

答案 0 :(得分:1)

您可以配置socket.io以断开窗口卸载时的连接。

请参阅Socket.io wiki中客户端的sync disconnect on unload选项。此选项默认为false,因此如果启用它,它应该可以解决您的问题。

app.gameSocket = io.connect('http://localhost/gameConnection', {'sync disconnect on unload':true}); //game connection

答案 1 :(得分:1)

Socket.io并不是那么有趣!

在我的应用中,每次退出>登录过程是

app.gameSocket = io.connect('http://localhost/gameConnection'); //game connection

因此多次调用它会导致问题。我把它改成了这样的东西:

app.firstConnect = true;

app.startGameSocket = function(){
    if(app.firstConnect){
        app.gameSocket = io.connect('http://localhost/gameConnection'); //game connection
    }else{
        app.gameSocket.socket.reconnect();
    }
}

app.vent.on('logOut', function(){
    app.firstConnect = false;
});

我的问题已经消失,但socket.reconnect引入了另一个问题!你可以在这里阅读https://github.com/LearnBoost/socket.io/issues/430

答案 2 :(得分:1)

套接字如何识别连接到它的各种客户端,连接时通过套接字参数。然后将所有其他事件分配给 socket.on 下的每个套接字客户端在io.connection块下。每当任何客户端连接或断开连接时调用自己的套接字事件(socket.on) socket.io 使用套接字参数识别它每个插座的ID。

<强>示例

io.sockets.on('connection', function(socket //unique client socket as parameter) {
 //code block
}

<强>例如

io.sockets.on('connection', function(socket) {
    //connect Me(socket)
    socket.on('connect', function() {
        console.log('disconnected')
    })
    //disconnect Me(socket)
    socket.on('disconnect', function() {
        console.log('disconnected')
    })
});

您的代码正在做什么

app.vent.on('logOut', function() {
    app.gameSocket.emit('forceDisconnect'); //force disconnect on the server side
    app.gameSocket.disconnect();
    app.gameSocket.removeAllListeners(); //tried to really kill disconnected socket
)};

它不会发出客户端特定套接字

的断开连接事件
app.gameSocket.emit('forceDisconnect'); //force disconnect on the server side

强制断开连接,但断开谁?

你需要这样的东西

app.startGameSocket = function() {
    app.gameSocket = io.connect('http://localhost/gameConnection'); //game connection

    app.gameSocket.on("connect", function() {
        console.log("connected to the game socket");
    });

    //disconnect
    app.gameSocket.on("disconnect", function() {
        console.log("disconnected");
        //force disconnect/logout code
    });

    app.gameSocket.on('logOut', function() {
        //force disconnect/logout code
        app.gameSocket.emit('forceDisconnect'); //force disconnect on the server side
        app.gameSocket.disconnect();
        app.gameSocket.removeAllListeners(); //tried to really kill disconnected socket
    )};

}