如何在 worker 之间共享动态对象?

How to share dynamic objects across workers?

我正在尝试制作一款适用于房间、大厅等的游戏(想象一下聊天应用程序,除了额外的 checks/information 存储)。

比方说,我有一个模块room.js

var EventEmitter = require('events');

class Room extends EventEmitter {
  constructor (id, name) {
    super();

    this.id = id;
    this.name = name;
    this.users = [];
  }
}

Room.prototype.addUser = function (user) {
  if(this.users.indexOf(user) === -1) {
      this.users.push(user);
      this.emit('user_joined', user);
  } else {
    /* error handling */
  }
};

module.exports = {
    Room: Room,
    byId: function (id) {
      // where should I look up?
    }
};

我怎样才能准确地得到这个对象(带有事件)?如何访问此对象发出的事件?

在单个节点实例中,我会做类似的事情:

var rooms = [];
var room = new Room(1234, 'test room');
room.on('user_joined', console.log);
rooms.push(room);

此外,我不太明白 Redis 究竟是如何提供帮助的(它是 EventEmitter 的替代品吗?)

此致。

编辑:也会接受 PM2 解决方案。

除了在 Node 中处理房间,你可以用 Redis 中的通道代替它们。

当一个新客户想要加入一个房间时,NodeJS 应用程序 returns 它会输入这个给定房间的 ID(即频道的名称),然后客户端 suscribes到选择的房间(你的客户端直接连接到Redis。

您可以使用 Redis Set 来管理房间列表。

在这种情况下,您不需要任何事件发射器,并且您的节点服务器是无状态的。

否则就意味着Redis会暴露在互联网上(假设你的游戏是public),所以你必须激活Redisauthentication。此解决方案的一个主要问题是您必须将服务器密码提供给所有客户端,因此绝对不安全。 此外,Redis 的性能允许暴力攻击,因此不建议将其暴露在 Internet 上。这就是为什么我认为所有通信都应该通过 Node 实例,即使 Redis 用作后端也是如此。

为了解决这个问题,您可以使用socket.io 打开Node 和您的客户端之间的套接字,并使Node 实例(而不是客户端)订阅Redis 通道。 Redis发布消息时,通过socket发送给客户端。并添加一层身份验证以确保只有有效的客户端才能连接到给定的通道。

不需要事件发射器。 Redis 客户端将成为事件发射器(如 example based on ioRedis