1

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

假设我有一个模块 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 解决方案。

4

1 回答 1

0

您可以用 Redis 中的通道替换它们,而不是在 Node 中处理房间)。

当一个新的客户端想要加入一个房间时,NodeJS 应用程序返回给它这个给定房间的 ID(即频道的名称),然后客户端订阅所选房间(您的客户端直接连接到 Redis .

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

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

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

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

不需要事件发射器。它将成为事件发射器的 Redis 客户端(如本示例中基于 ioRedis

于 2016-10-24T08:25:40.183 回答