如何跨工作者共享动态对象



我正在尝试制作一款适用于房间,大厅等地方的游戏(想象一下聊天应用,除了额外的检查/信息存储)。

比如说,我有一个模块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?
    }
};

我怎么能得到这个对象(与事件)?如何访问该对象发出的事件?

在node的单个实例中,我会这样做:

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

另外,我不太明白Redis实际上是如何帮助的(它是EventEmitter的替代品吗?)

致意。

编辑:也会接受PM2方案

你可以用Redis中的通道代替Node中的房间。

当一个新的客户端想要加入一个房间时,NodeJS应用程序返回给它这个给定房间的ID(也就是说通道的名称),然后客户端订阅选定的房间(你的客户端直接连接到Redis。

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

在这个场景中,您不需要任何事件发射器,并且您的节点服务器是无状态的。

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

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

事件发射器不是必需的。它是Redis客户端,它将是一个事件发射器(就像在这个例子中基于ioRedis)

最新更新