Ich benutze Node.js und Redis. Ich versuche, einen zuverlässigen Weg zu finden, um Spieler automatisch abzufangen. Es gibt einen passenden Server und dann mehrere Spieleserver.
Folgendes muss geschehen sein:
- Der Spieler sendet eine Beitrittsanfrage mit Spieltyp (klein / mittel usw.)
- Der passende Server fügt den Spieler dem aktuellen Spieltyp hinzu, der auf die Spieler wartet
- Der Spieleserver sendet dem Spieler die Spiel-ID
Derzeit habe ich dies wie folgt implementiert:
- Passender Server hört auf Spiel: Warteschlange: klein mit BRPOP
- Überprüft, ob game: queue: small: id = id vorhanden ist
- Überprüft, ob das Spiel: id: Benutzerlänge <= 6 ist (max. Spieler)
- Fügt Spieler zum Spiel hinzu: id: Benutzerliste, falls vorhanden
- Wenn die Spiellänge jetzt 6 ist, wird game: queue: small: id entfernt
Wenn der übereinstimmende Server das Spiel findet: queue: small: id fehlt, geschieht dies wie folgt:
- INCR-Spiel: nextGameId
- Setzt game: queue: small: id auf die zuvor generierte ID
- Fügt die Spiel-ID zum Spiel hinzu: Warteschlange: Warten
Die Spieleserver warten mit BRPOP auf neue Spiele. Wenn sie einen bekommen, warten sie, bis das Spiel mindestens 2 Benutzer hat, und starten dann einen Timer. Wenn sie diese Zeit nicht ausfüllen, beginnen sie mit den Benutzern, die sie haben, und entfernen anschließend game: queue: small: id (wodurch der Matchmaker gezwungen wird, ein neues Spiel anzufordern).
Während meine Methode funktioniert, bin ich nicht davon überzeugt, dass sie in der Produktion gut funktionieren wird, und sie scheint sehr kompliziert zu sein. Ich kann das Potenzial für die folgenden Probleme erkennen:
- Der Spieleserver stürzt ab, nachdem die Spiel-ID von der Warteliste akzeptiert wurde, was dazu führt, dass Benutzer zum Spiel hinzugefügt werden: id: Benutzer, aber nichts passiert mit ihnen (der Absturz selbst ist kein Problem, aber Benutzer, die weiterhin zu dieser Spielewarteschlange hinzugefügt werden, sind )
- Wenn ein Benutzer die Verbindung trennt und das Spiel noch nicht gestartet wurde, entfernt der Spieleserver den Benutzer aus der Liste game: id: users. Währenddessen könnte der Matchmaking-Server einen Benutzer zur Liste hinzufügen und denken, dass das Spiel voll ist, wodurch er aus der Warteschlange entfernt wird.
Meine ersten Gedanken waren, zu einer einzigen Warteschlange von Benutzern zu wechseln, die auf einen Spieltyp warten. Dies wirft jedoch weitere Probleme auf:
- Wenn der Server, zu dem die Benutzer eine Verbindung herstellen, abstürzt, wird der Benutzer nicht aus der Warteschlange entfernt, sodass dieser Benutzer in ein Spiel aufgenommen werden kann, wenn er nicht vorhanden ist. Ich könnte sortierte Sätze verwenden, um die Zeit der Anfrage zu speichern und die Client-Umfrage durchzuführen, bis eine Spiel-ID zurückgegeben wird. Dies würde jedoch bedeuten, dass ich keine Ahnung habe, wie lange dieser Client gewartet hat und daher nicht weiß, ob ich das Spiel starten soll mit weniger Benutzern.
- Ohne die Benutzer in ein Spiel einzubeziehen, können sie weder sehen, was Benutzer beigetreten sind, noch mit den wartenden Benutzern chatten (da hierfür eine Spiel-ID erforderlich ist).
Die Art und Weise, wie ich dies eingerichtet habe, fühlt sich nicht richtig an, also hoffte ich, dass jemand in der Lage sein könnte, bessere Vorschläge zu machen. Ich muss die Spielserver und die Matchmaking-Server wirklich getrennt halten, um sie nach Bedarf zu vergrößern.