在 Socket.IO 客户端断开连接时释放事件处理程序

Release event handlers on disconnection of Socket.IO client

我正在使用 Socket.IO,就像在这个示例中一样:

io.sockets.on("connection", function (socket) {

    myService.on("myevent", function() {
        socket.emit("myevent", { /* ... */ });
        // some stuff happens here of course
    });

});

myService 是一个单例,是 EventEmitter 的子类,随着时间的推移会触发 myevent。一切正常,但我想我在这种情况下造成了某种泄漏。一旦连接被破坏,我的服务如何知道它不需要调用处理程序?有没有我可以捕获的某种破坏事件,然后从 myService?

中删除处理程序

侦听套接字断开连接事件,当您收到断开连接事件时,从 myService 对象中删除相关事件处理程序。

你应该可以这样做:

io.sockets.on("connection", function (socket) {

    function handler() {
        socket.emit("myevent", { /* ... */ });
        // some stuff happens here of course
    }

    myService.on("myevent", handler);

    socket.on("disconnect", function() {
        myService.removeListener("myevent", handler);
    });

});

如果你想做的是向所有连接的套接字广播,你可以只安装一个 "myevent" 侦听器(不是每个连接一个)并使用 io.emit() 向所有套接字广播也不必为此目的处理连接或断开连接事件。

如果您计划在其他事件触发时向所有套接字发送数据,则不需要每次客户端 connects/disconnects.

时都 add/remove 另一个侦听器

使用 io.sockets (which is a reference to the default namespace with all clients on it by default) and io.sockets.emit:

将 socket.io 事件简单地触发到现在连接的所有套接字会更有效也更容易
myService.on('myevent', () => {
  io.sockets.emit('myevent', {/*...*/});
});

如果您只需要向部分用户触发此事件,请尝试使用特定的 namespaces or rooms:

myService.on('myevent', () => {

  //with namespaces
  io.of('namespace').emit('myevent', {/*...*/});

  //with rooms
  io.to('room').emit('myevent', {/*...*/});

});