简体   繁体   English

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

[英]Socket.io not firing events properly after disconnecting

So I wanted to build a little game app with socket.io, it works like that: 所以我想用socket.io构建一个小游戏应用程序,它的工作原理如下:

User loads a website and I create a general socket using generalConnection namespace 用户加载网站,我使用generalConnection命名空间创建一个通用套接字

app.generalSocket = io.connect('http://localhost/generalConnection');

I don't have any special events on it yet, but I thought it would be nice to keep it separate from a second namespace. 我还没有任何特殊事件,但我认为将它与第二个命名空间分开会很好。

When the user logs in I call a function that starts game connection (another namespace) and bind some events to it, I won't list them all, I think it's not important. 当用户登录时,我调用一个启动游戏连接的函数(另一个命名空间)并将一些事件绑定到它,我不会将它们全部列出,我认为这并不重要。

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

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

On the server side I have something like that: 在服务器端我有类似的东西:

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

Once again, I don't think I need to list all the events, I'll just explain how it works. 再一次,我认为我不需要列出所有事件,我只会解释它是如何工作的。

It listens to new player event, creates new player, pushes it connectedPlayers array and then sends it to everybody who is connected to gameConnection namespace. 它会监听新玩家事件,创建新玩家,将其推送到connectedPlayers数组,然后将其发送给连接到gameConnection命名空间的所有人。

User list is updated and everybody's happy. 用户列表已更新,每个人都很高兴。 I can also listen to other events like disconnect and update the connectedPlayers array appropriately when user closes the browser window. 当用户关闭浏览器窗口时,我还可以监听其他事件,例如断开连接并适当更新connectedPlayers数组。

I also had to disconnect the gameConnection namespace when users log outs from the game, so on the client side I do: 当用户从游戏中注销时,我还必须断开gameConnection命名空间,所以在客户端我做:

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

Notice that I keep generalConnection namespace open, I just disconnect the gameConnection namespace. 请注意,我将generalConnection命名空间保持打开状态,我只是断开了gameConnection命名空间。

It works nice, if user logouts or closes window, disconnect event is triggered on the server side, connectedPlayers array is updated and sent back to connected players. 它运行良好,如果用户注销或关闭窗口,在服务器端触发断开事件,connectedPlayers阵列更新并发送回连接的播放器。

The problem 问题

When user: 当用户:

  1. Enters website. 进入网站。
  2. Logs in to the game. 登录游戏。
  3. Logs out. 退出。
  4. Logs in again without refreshing window (triggers app.startGameSocket function again). 无需刷新窗口再次登录(再次触发app.startGameSocket函数)。
  5. And after all that closes the window, the gameConnection namespace disconnect event is not triggered on the server and list is not updated. 在关闭窗口之后,不会在服务器上触发gameConnection命名空间断开事件,并且不会更新列表。

Node shell says stuff like: info - transport end (socket end) but not triggers the disconnect event. Node shell表示类似:info - 传输结束(套接字结束)但不触发disconnect事件。 Please help :) 请帮忙 :)

I tried to 我试过了

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
)};

But no results. 但没有结果。

You can configure socket.io to disconnect the connection on window unload. 您可以配置socket.io以断开窗口卸载时的连接。

See the sync disconnect on unload option of the client in the Socket.io wiki . 请参阅Socket.io wiki中客户端的sync disconnect on unload选项。 This option defaults to false, so it should solve your problem if you enable it. 此选项默认为false,因此如果启用它,它应该可以解决您的问题。

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

Socket.io is not so much fun! Socket.io并不是那么有趣!

In my app each log out > log in process was 在我的应用程序中,每次注销>登录过程都是

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

So calling it multiple times like that was causing problems. 因此多次调用它会导致问题。 I've changed it to something like this: 我把它改成了这样的东西:

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;
});

My issues are gone, but socket.reconnect introduces another! 我的问题已经消失,但socket.reconnect引入了另一个问题! You can read about it here https://github.com/LearnBoost/socket.io/issues/430 你可以在这里阅读它https://github.com/LearnBoost/socket.io/issues/430

How socket identifies various client connected to it is, via socket parameter while connection. socket如何识别连接到它的各种客户端,在连接时通过socket参数 Then all other other event gets assigned to each socket-client under io.connection block as socket.on . 然后将所有其他事件分配给io.connection块下的每个套接字客户端作为socket.on Whenever any client gets connected or disconnected its own socket event(socket.on) gets called and socket.io identifies it with that socket paramenter and id of each socket. 每当任何客户端连接或断开连接时, 它自己的套接字事件(socket.on)都会被调用,socket.io会使用该套接字参数和每个套接字的id来识别它。

Sample 样品

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

Eg: 例如:

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')
    })
});

What your code doing is 你的代码在做什么

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
)};

its not emitting disconnect event of client specific socket 它不会发出客户端特定套接字的断开事件

app.gameSocket.emit('forceDisconnect'); //force disconnect on the server side

Force disconnect but disconnect whom? 强制断开但断开谁?

You need something like this 你需要这样的东西

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
    )};

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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