首页 > 解决方案 > 从 EventEmitter 附加事件函数数组中删除断开连接时的 Socket.IO 发射器

问题描述

我有 EventEmitter 和 socket.io 协同工作,它们按我期望的方式工作。我有一个包含数据的对象,该数据可以在任何时间点随机更改,当数据更改时,它会使用更新的数据触发 EventEmitter.emit。

在另一个文件中,我有一个 EventEmitter.on,它捕获该数据并将其传递给 socket.emit 以发送到前端,如下所示:

在包含数据的对象中:

UpdateIfDataIsNew(newData, oldData) {
  if (newData !== oldData) { //simplified, not exactly like this
    eventBus.emit('dataEvent', newData)
  }
}

其中 eventBus 是一个全局 EventEmitter 对象。

在我处理向前端发送数据的文件中,代码大致是:

ioServer.on("connection", (socket) => {
  eventBus.on("dataEvent", (data) => {
    socket.emit("frontEndDataEvent", data);
  });
})

其工作方式是,每当有新用户连接时,就会创建一个新套接字,并在触发“dataEvent”时将一个新的 socket.emit 添加到要触发的函数列表中,以便所有连接的用户都收到更新的数据。问题是当特定用户断开连接时,我不知道如何从函数的 eventBus 数组中删除特定的 socket.emit,因为当我不这样做时,所有函数都保留在事件数组中,并且所有函数触发事件时触发,尽管这些用户不再在网站上,但最终数组变得非常大,即使是单个用户的简单刷新,也会不断向数组添加越来越多的功能。

我知道我可以查看用户是否已断开连接,socket.on("disconnect", ???)但那又如何呢?

http://prntscr.com/tou4pw功能是一样的,只是socket不同,当有人断开连接时,如何找到必须删除的那个?

除了向 eventEmitter 添加一个函数之外,我还可以添加一个包含 ID: 和函数的对象,以便我可以快速识别我必须删除的对象吗?

标签: node.jseventssocket.io

解决方案


我通过创建自己的 Event Emitter 类(扩展 EventEmitter)解决了这个问题,这样我就可以控制给定事件的函数数组,并且还可以分配一个 ID。

const EventEmitter = require("events");

class RobotData extends EventEmitter {
  constructor() {
    super();
    this.emitters = [];
  }

  add(socket, dataType) {
    this.emitters.push({
      socket,
      dataType,
      trigger: (eventName, newData) => {
        socket.emit(`${eventName}`, newData);
      },
    });
  }

  remove(ID) {
    this.emitters = this.emitters.filter((emitter) => emitter.socket.id !== ID);
  }
}

const robotData = new RobotData();

module.exports = { robotData };

然后在断开连接事件中:

socket.on("disconnect", () => {
  robotData.remove(socket.id);
});

推荐阅读