Zitat von
.chicken:
Kann ich die uses nicht wie folgt anordnen?
[delphi]
Server
uses
Connector
Connector
uses
Controller
Controller
uses
Server
[*delphi]
Ich glaube das Du da immer noch einen totalen Denkfehler drin hast. Du musst den Server komplett getrennt vom Client betrachten. Stell Dir einfach vor, Du hättest hier wirklich zwei Programme laufen. Bei vielen Client/Server Anwendungen ist das ja der Fall (Google läuft auf einem Webserver, auf einem Cluster, Dein Webbrowser wohl eher auf Deinem Rechner).
Die beiden Programme kommunizieren über einen bestimmten Kanal. Wie sie dabei Daten austauschen legt das Protokoll fest.
Ich hab die Idee noch mal grafisch aufbereitet (nicht all zu hübsch, aber vielleicht trotzdem leichter verständlich). Schau einfach mal in das angehängte PDF.
Auf der ersten Seite findest Du dann den Ablauf, wie es grob aussehen könnte, wenn ein Spieler eine Aktion ausführt. Es beginnt bei der
GUI, wo der Benutzer irgendwas macht (z.B. einen Button anklickt). Das ganze ist ein Ereignis, wird behandelt und dem "Client Game Controller" mitgeteilt. Dieser Name mag etwas verwirrend sein und ist natürlich nicht bindend, es geht hier nur darum, dass man die einzelnen Teile gut unterscheiden kann.
Der "Client Game Controller" hat eine einfache Aufgabe, man teilt ihm mit, was gemacht wurde (irgendwie kommt das von der
GUI rein). Er wandelt das dann in ein Format um, dass direkt übertragen werden kann (entspricht dem Protokoll, dass dein Server verwendet). Ich sag hier einfach mal (o.B.d.A.) es sein ein String. Dieser String wird dann an eine Komponente weitergereicht, die mit dem Server verbunden ist (der
TCP-Client). Dieser verschickt (ohne weitere Logik) einfach einen String und gut ist.
Das ist auch alles, was auf Seiten des Clients soweit passiert. Weiter geht es auf der anderen Seite, dem Server. Hier wird vom
TCP-Server eine eingehende Anfrage empfangen. Die wird er lesen und (hoffentlich) das Protokoll kennen. Diese Anfrage reicht der
TCP-Server einfach weiter an den "Server Game Controller". Dieser wandelt den empfangenen String einfach in eine Änderung des Zustands um. Diese Änderung wir nun am "Game Server" vorgenommen. Der Name hier ist sehr schlecht gewählt, mir fällt aber kein guter ein. Mit Game-Server meine ich den kompletten Zustand des Spiels und Methoden diesen zu verändern. Wird der Zustand verändert, muss dies zu einer Benachrichtigung aller Clienten führen, das alles steckt schon in diesem Game-Server drin. Natürlich soll der dabei gar nicht eine eigenständige Komponente sein, hier gehe ich nur nicht näher ins Detail!
Ja, soweit war es das auch schon. Jetzt wurde der Zustand im Server geändert. Was wie gesagt implizit passieren muss, sobald sich ein solcher Zustand ändert ist, dass der Server allen Clients diese Änderungen mitteilt. Das siehst Du dann auf der zweiten Seite des PDF.
Hier spricht der Server einen "Update Controller" an. Auch dieser Name ist wohl etwas schlecht gewählt. Die Aufgabe dieser Komponente ist aber wieder leicht. Sie bekommt ein Änderungsereignis vom Server mitgeteilt und wandelt diese Änderung in einen String, der übertragen werden kann. Für jeden bekannten Client passieren die folgenden Schritte (auch wenn hier nur einer angezeigt wird).
Wurde der String erzeugt, wird der einfach an den
TCP-Server gereicht*, der diesen String an die Zieladresse verschickt.
Auf Seiten des Servers war es das schon. Auf der anderen Seite wird nun der String vom
TCP-Client empfangen* und an den "Client
GUI Controller" weiter gereicht. Dieser macht eigentlich nichts anderes als das empfangene Ereignis darzustellen. Dazu parst dieser Controller einfach das Ereignis/den String und sagt der
GUI, was sie anzeigen soll.
Das ist auch schon alles. Wie Du siehst, gibt es hier gleich 8 dargestellte Komponenten, was aber nur viel wirkt. Das eigentlich wichtige sind die Pfeile und ihre Richtung. Die wichtigste Sonderrolle nimmt die Linie ein, die durch das Netzwerk geht. Da sie durch das Netzwerk geht, soll sie wirklich eine
TCP/
IP Verbindung darstellen und muss gesondert betrachtet werden.
Die anderen Pfeile zeigen an, wer wen kennen muss. So greift das
GUI auf die "Client Game Controller" Komponente zu, aber nicht umgekehrt. Diese wiederum verwendet den
TCP-Client, aber nicht umgekehrt. Der ist über diesen gesonderten Kanal mit einem Server verbunden. Geh einfach die anderen Pfeile durch und Du siehst, dass sich hier keine zwei Komponenten gegenseitig kennen müssen.
Natürlich kannst Du jetzt sagen, dass das für Server und Client gilt, aber hier kommt wie gesagt ein gesonderter Kanal zum Einsatz. Dabei kennt der
TCP-Client nicht wirklich den Server und umgekehrt, es sind nur die
IP-Adressen und Ports des jeweiligen anderen bekannt, die Units müssen sich hingegen nicht kennen!
Vielleicht ist es ein guter Anfang, wenn Du die beiden Programmteile erstmal so entwickelst, dass Du doch erst einen getrennten, unabhängigen Server hast. Dann kann man Dir später helfen, wie Du den ins normale Spiel integrierst. Dabei solltest Du schon darauf achten, dass Du keine zwei Units in den beiden Programmen gleich nennst. So ist sicherlich auf beiden Seiten mindestens ein Controller zu finden, sie haben jedoch komplett unterschiedliche Aufgaben (der eine hat nur mit der Client, der andere nur mit der Server Seite zu tun). Gibt es Units die auf beiden Seiten bebraucht werden (die z.B. Konstanten enthalten oder Datentypen,...), dann pack die einfach in einen getrennten Ordner und füge sie beiden Projekten hinzu (Gelber Ordner mit grünem Plus oder unter Projekt -> Hinzufügen, denke ich). Dann kannst Du die gleiche
Unit in beiden Teilen verwenden. Die Datei kopieren wäre hingegen ganz schlecht, hier könnte es schnell zu Update-Anomalien kommen.