node.js - 从 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: 和函数的对象,以便我可以快速识别我必须删除的对象吗?
解决方案
我通过创建自己的 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);
});
推荐阅读
- notepad++ - 为什么我的正则表达式在 Notepad++ 编辑器中显示无效?
- django - /candidate/1/ 处的类型错误
- components - 防止嵌套 TeeChart 在设计时接收鼠标事件
- css - 如何在 React JS 上使用 type = date 设置 TexField 组件的样式
- sum - 使用 order powerquery 的列总和
- automated-tests - 空手道 - 如何更改某些 html 标签中的文本
- asp.net - .Net Core 身份登录页面无法在 IIS 上运行托管应用程序
- solr - 在多个 Solr 字段中搜索值
- android - Android,以GridLayoutManager和ImageView为单元格内容的RecyclerView不适合垂直空间
- spring-boot - 如何在spring-resource-server中获取OidcUser,而不是在@AuthenticationPrincipal中获取Jwt?