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

Node でルームを処理する代わりに、それらを Redis のチャネルに置き換えることができます)。

新しいクライアントがルームに参加したい場合、NodeJS アプリはこの指定されたルームの ID (つまり、チャネルの名前) を返し、クライアントは選択されたルームを購読します (クライアントは Redis に直接接続されています) .

Redis Setを使用して、ルームのリストを管理できます。

このシナリオでは、イベント エミッターは必要なく、ノード サーバーはステートレスです。

そうしないと、Redis がインターネット上で公開されることを意味するため (ゲームが公開されている場合)、Redis認証を有効にする必要があります。このソリューションの主な問題は、サーバーのパスワードをすべてのクライアントに提供する必要があることです。そのため、確実に安全ではありません。さらに、Redis のパフォーマンスはブルート フォース攻撃を可能にするため、インターネット上に公開することはお勧めしません。そのため、Redis がバックエンドとして使用されている場合でも、すべての通信は Node インスタンスを経由する必要があると思います。

これを解決するには、socket.io を使用して Node とクライアントの間でソケットを開き、(クライアントではなく) Node インスタンスを Redis チャネルにサブスクライブさせます。メッセージが Redis によってパブリッシュされると、ソケットを介してクライアントに送信されます。また、認証レイヤーを追加して、有効なクライアントのみが特定のチャネルに接続するようにします。

イベント エミッターは必要ありません。イベント エミッターになるのは Redis クライアントです (この例では ioRedis に基づいています)

于 2016-10-24T08:25:40.183 に答える