Ich schreibe also ein Schach-Matchmaking-System, das auf einer Lobby-Ansicht mit Spielräumen, allgemeinem Chat usw. basiert. Bisher habe ich einen funktionierenden Prototyp, aber ich habe große Zweifel an einigen Dingen, die ich mit dem Server gemacht habe. Das Schreiben eines Gaming-Lobby-Servers ist für mich eine neue Programmiererfahrung und daher habe ich kein klares oder präzises Programmiermodell dafür. Ich konnte auch kein Papier finden, das beschreibt, wie es funktionieren sollte. Ich habe "Java Network Programming 3rd Edition" bei Amazon bestellt und warte immer noch auf den Versand. Hoffentlich finde ich in diesem Buch einige nützliche Beispiele / Informationen.
In der Zwischenzeit möchte ich Ihre Meinungen sammeln und sehen, wie Sie mit einigen Dingen umgehen würden, damit ich lernen kann, wie man einen Server richtig schreibt. Hier sind ein paar Fragen aus meinem Kopf: (Vielleicht werden noch mehr kommen)
Definieren wir zunächst, was ein Server tut. Die Hauptfunktion besteht darin, TCP-Verbindungen mit Clients aufrechtzuerhalten, die von ihnen generierten Ereignisse abzuhören und sie an die anderen Spieler zu senden. Aber steckt noch mehr dahinter?
Soll ich einen Thread pro Client verwenden? Wenn ja, sind 300 Clients = 300 Threads. Ist das nicht zu viel? Welche Hardware wird benötigt, um das zu unterstützen? Und wie viel Bandbreite verbraucht eine Lobby dann ca.
Welche Art von Datenstruktur sollte verwendet werden, um die Sockets der Clients zu halten? Wie schützen Sie es vor gleichzeitigen Änderungen (z. B. wenn ein Spieler die Lobby betritt oder existiert), wenn Sie es durchlaufen, um ein Ereignis auszulösen, ohne den Durchsatz zu beeinträchtigen? Ist ConcurrentHashMap hier die richtige Antwort oder gibt es einige Techniken, die ich kennen sollte?
Welchen Mechanismus würden Sie verwenden, wenn ein Benutzer die Lobby betritt, um den Status der Lobby auf ihn zu übertragen? Und währenddessen sprudeln die anderen Ereignisse in die Luft?
Antworten:
Modellieren Sie alles als Objekte. Sie haben die Klassen Chat-Raum, Spiel-Sitzung, Spieler ... Laichen Sie keine neuen Threads für neue Spieler. Versuchen Sie stattdessen, jede Klasse als Zustandsmaschine zu betrachten: Ein Spieler kann verbunden oder getrennt werden, er hat eine TcpConnection und eine Variable, die angibt, wie viel Zeit er noch hat, um seinen Zug auszuführen (nur als Beispiel).
Wenn Sie dann alle Ihre Objekte in einem Array oder ähnlichem haben, iterieren Sie alle 10 Millisekunden darüber (die Zahl ist natürlich auch ein Beispiel) und ergreifen geeignete Maßnahmen.
Beenden Sie beispielsweise eine Spielsitzung, wenn einer der Spieler das Spiel verlassen hat, und senden Sie Züge von einem Spieler zum anderen ...
Für alle Ereignisse im Spiel müssen Sie eine Nachricht über das Netzwerk senden. Erstellen Sie eine zusätzliche Klasse / Aufzählung, die die verschiedenen Nachrichtentypen enthält. Wenn ein Spieler einen Zug macht, können Sie diesen an den Server senden "Zug d4 nach d5" oder so. Wenn Sie nur ein Schachspiel machen, können Sie Zeichenfolgen durch das Netzwerk senden. Für etwas komplexeres würde ich vorschlagen, dass Sie nur einzelne Bytes senden.
Typischerweise bestehen Spielpakete aus: der Länge des Pakets, dem Paketnachrichtentyp / Ereignistyp (Verschieben, Spieler verbunden, Spieler links, ...) und dem Inhalt (wenn ein Spieler beitritt, wäre der Inhalt der Name für Beispiel)
quelle
Um die Anzahl der benötigten Threads zu begrenzen, sollten Sie sich Java NIO ansehen: http://en.wikipedia.org/wiki/New_I/O
quelle