【问题标题】:Release event handlers on disconnection of Socket.IO client在 Socket.IO 客户端断开连接时释放事件处理程序
【发布时间】:2015-04-30 16:20:24
【问题描述】:

我在这个示例中使用 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 是什么,它的生命周期是什么,甚至与套接字有什么关系。 myService 是单例什么的?您可以监视disconnect 事件并在那里做一些事情。
  • 正如我的问题中提到的myService 是一个单身
  • 单身什么?它是什么类型的对象?它有什么作用?它有哪些方法?它与插座有什么关系?单例仅意味着只有其中一个。它没有告诉我们它是什么类型的对象,它的用途是什么以及它是如何使用的?您在这里只披露了大约 1/3 的相关问题。
  • 是的,如果套接字连接,然后断开连接并且未删除相关的 myService 事件处理程序,您确实会出现内存泄漏。您的 myService.on() 事件处理程序将保留对 socket 的关闭引用,即使它早已关闭。我们必须知道 myService 是什么以及如何从中删除事件处理程序才能知道建议什么。
  • @jfried00:无论如何,这是一个笼统的问题,所以不需要知道它的目的或它是哪种类型的对象。当谈到单例时,我的意思是一个对象,它被实例化一次,然后在整个进程生命周期中保持,并在需要它的所有地方重用。

标签: javascript node.js socket.io


【解决方案1】:

监听socket断开事件,当你收到断开事件时,从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() 也向所有套接字广播而不必处理用于此目的的连接或断开连接事件。

【讨论】:

  • 谢谢。而已。我错过的部分是disconnect 事件。但是我的问题不清楚,很抱歉,感谢您的帮助。
  • @miho - 我添加了一个代码示例,现在我知道myServiceEventEmitter
  • 谢谢。只是一些小的更正,它是removeListener 而不是removeEventListener
  • 当您只想向所有客户端广播消息时,向单个套接字添加/删除侦听器不是一个好习惯。检查我的答案以获得更有效和更清洁的解决方案。
  • @diegonunes - 您正在对问题中未说明的 OP 情况做出一些假设。也许是这样,也许不是。他们询问如何在套接字断开连接时删除事件侦听器,因此我向他们展示了如何正确执行此操作。而且,为此,你对我投了反对票。哎呀。如果你的答案更好,它应该会得到更多的支持。您不需要仅仅因为您认为自己有更好的方法而对正确答案投反对票。如果 OP 提供了有关整体问题的更多背景信息,我们可能都可以在总体方案中提供更有用的答案。
【解决方案2】:

如果您计划在其他事件触发时向所有套接字发送数据,则无需在每次客户端连接/断开连接时添加/删除其他侦听器。

使用io.sockets(这是对默认命名空间的引用,默认情况下所有客户端都在其上)和 @ 987654322@:

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', {/*...*/});

});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    • 2017-07-17
    • 2012-05-17
    • 1970-01-01
    • 2018-02-09
    • 2015-12-23
    • 1970-01-01
    相关资源
    最近更新 更多