Node.jsとRedisを使用しています。プレイヤーをオートマッチする信頼できる方法を考え出そうとしています。一致するサーバーがあり、複数のゲームサーバーがセットアップされています。
以下は私が起こらなければならないことです:
- プレーヤーはゲームの種類(小/中など)で参加リクエストを送信します
- マッチングサーバーは、プレーヤーを待っている現在のゲームタイプにプレーヤーを追加します
- ゲームサーバーはプレイヤーにゲームIDを送信します
現在、私はこれを次のように実装しています:
- マッチングサーバーはBRPOPを使用してgame:queue:smallをリッスンします
- game:queue:small:id = idが存在するかどうかを確認します
- game:id:usersの長さが<= 6(最大プレーヤー)かどうかを確認します
- プレーヤーをgame:id:usersリストに追加します
- ゲームの長さが6になったら、game:queue:small:idを削除します
一致するサーバーがgame:queue:small:idがないことを検出すると、次のようになります。
- INCRゲーム:nextGameId
- game:queue:small:idを以前に生成されたIDに設定します
- ゲームIDをgame:queue:waitingに追加します
ゲームサーバーは、BRPOPを使用して新しいゲームを待ちます。ユーザーが1人になると、ゲームのユーザーが2人以上になるまで待ってから、タイマーを開始します。それらがその時間内に満たされない場合、それらは持っているユーザーから始まり、その後game:queue:small:idを削除します(したがって、マッチメーカーに新しいゲームを要求するよう強制します)。
私の方法が機能している間、私はそれが生産でうまく機能すると確信していません、そしてそれは非常に入り組んでいるようです。次の問題の可能性を確認できます。
- 待機リストからゲームIDを受け入れるとゲームサーバーがクラッシュし、ユーザーはgame:id:usersに追加されますが、何も起こりません(クラッシュ自体は問題ではありませんが、ユーザーがゲームキューに追加され続けると、 )
- ユーザーが切断してゲームが開始されていない場合、ゲームサーバーはユーザーをgame:id:usersリストから削除します。それを行っている間、マッチメイキングサーバーはユーザーをリストに追加して、ゲームがいっぱいであると考え、キューから削除することができます。
私の最初の考えは、1つのゲームタイプを待っているユーザーの単一のキューに変更することでした。ただし、これにはさらに問題があります。
- ユーザーが接続するサーバーがクラッシュした場合、ユーザーをキューから削除しないため、ユーザーが存在しない場合でも、そのユーザーはゲームに参加できます。ソートされたセットを使用してリクエストの時間を保存し、ゲームIDが返されるまでクライアントにポーリングさせることができますが、これは、そのクライアントがどれだけ待機したかわからないため、ゲームを開始するかどうかわからないことを意味しますユーザー数が少ない。
- ユーザーをゲームに参加させないと、ユーザーが参加しているものを確認したり、待機しているユーザーとチャットしたりできません(ゲームIDが必要になるため)。
私がこれを設定した方法はどれも正しくないので、誰かがいくつかのより良い提案を提供できるかもしれないと思っていました。ゲームサーバーとマッチメイキングサーバーを別々にしておく必要がありますが、必要に応じて拡張するためです。