NodeJS 数组和 firebase 引用获取垃圾收集

NodeJS array and firebase reference getting garbage collected

我希望能够在第一个用户连接到 socket.io 房间时创建一些 firebase 引用,然后监听这些 firebase 引用的变化,并写入文件。

现在我的方法是拥有一个全局 Map 对象,然后将 firebase 引用和文件名作为对象的一部分分配给数组。然后存储对象,到全局地图。 不幸的是,一旦第一次连接的功能结束,引用就会丢失。我可以通过让另一个用户连接/刷新页面并记录全球地图来看到这一点。

这是我的代码的样子。

io.on('connect', (socket) => {
    io.to(socket.id).emit('create-room');
    socket.on('join-room', (roomId: string) => {
      socket.join(roomId);
      try {
        console.log(activeWorkers)
        if (!activeWorkers.get(roomId)) {
          // if not in global map, tell user he is first in room so that we can get additional info
          io.to(socket.id).emit('first-in-room');
        } else {
          console.log(activeWorkers.get(roomId));
        }
      } catch(err) {
        console.log(err);
      }
    });
    socket.on('create-worker', async (roomId: string, additionalInfo: string) => {
      // first user sent back additional info;
      let firebaseRefObj = new FirebaseRefObj(roomId, additionalInfo); // an object that stores the references and file paths

      activeWorkers.set(roomId, {
        id: roomId,
        worker: firebaseRefObj
      }); // store in global map
      firebaseRefObj.createRefs(); // create references, the references add initial values to firebase, then watch for changes to update local files.
    })
    socket.on("disconnect", () => {
      socket.removeAllListeners();
    });
  })

这是因为 socket.io 函数不会在 on 事件中保留它们的变量,如果您稍后尝试访问 firebaseRefObj,则必须存储它放入数组或对象映射中,以便您可以将该用户与其重新关联。

您可以使用已有的房间 ID,并将其作为引用列表中值的名称传递 {[roomId]: firebaseRefObj}

就我个人而言,我强烈建议针对此用例使用 enmapenmap 就像 node.js 的 C# 字典。当您启动脚本并声明变量时,在顶部添加一个新的 enmap 来存储您的 ref 对象。

我相信以下方法会奏效:

const Enmap = require("enmap");
const FirebaseRefs = new Enmap();

// ...
FirebaseRefs.set(RoomId, FirebaseRefsObj);

您可以在这里阅读基础知识:https://enmap.evie.dev/usage/basic

来源:https://www.npmjs.com/package/enmap

Enmap 是一个非常好的解决方案,但我的问题在于我使用我的 firebase 引用的原因。我在内部使用 firepad,它本身与超出范围的 firebase 参考一起使用。

删除 firepad 解决了我的问题。