Projekt:2021/WORDLE: Unterschied zwischen den Versionen

Zur Navigation springen Zur Suche springen
4.507 Bytes hinzugefügt ,  21:29, 27. Mär. 2022
Keine Bearbeitungszusammenfassung
 
(9 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 9: Zeile 9:
Modelliert und implementiert zu zweit einen [https://wordle.uber.space Wordle] Server, der das im Unterricht entwickelte WOPP3 vollständig umsetzt.
Modelliert und implementiert zu zweit einen [https://wordle.uber.space Wordle] Server, der das im Unterricht entwickelte WOPP3 vollständig umsetzt.
{{Aufgabe:End}}
{{Aufgabe:End}}
 
{{Rahmen|
# Modelliert das Server-Programm, indem ihr gemeinsam ein ''Implementierungsdiagramm'' für das Projekt erstellt. Modelliert auch die wichtigsten Abläufe des Spiels als ''Sequenzdiagramme'' (Anmeldung, WOTD spielen, ein Spiel pausieren/fortsetzen, ...). Speichert die UML-Dateien im Projektordner im Unterordner <code>modell</code>.
# Modelliert das Server-Programm, indem ihr gemeinsam ein ''Implementierungsdiagramm'' für das Projekt erstellt. Modelliert auch die wichtigsten Abläufe des Spiels als ''Sequenzdiagramme'' (Anmeldung, WOTD spielen, ein Spiel pausieren/fortsetzen, ...). Speichert die UML-Dateien im Projektordner im Unterordner <code>modell</code>.
# Modelliert ein ''Datenbankschema'' für die Umsetzung des Spiels.
# Modelliert ein ''Datenbankschema'' für die Umsetzung des Spiels.
# Implementiert den Wordle-Server so, dass das vereinbarte Protokoll möglichst exakt umgesetzt wird. Beachtet die Hinweise unten auf dieser Seite.
# Implementiert den Wordle-Server so, dass das vereinbarte Protokoll möglichst exakt umgesetzt wird. Beachtet die Hinweise unten auf dieser Seite.}}


=== Gruppen ===
=== Gruppen ===
Zeile 18: Zeile 18:
* Maja, Simon
* Maja, Simon
* Alperen, Tim
* Alperen, Tim
* Malin, Enno, Oliver
* Malin, Enno
* Hung, Jan
* Hung, Jan
* Maxim, Artem
* Maxim, <del>Oliver</del>, Artem


=== Links ===
=== Links ===
Zeile 101: Zeile 101:
-ERR wotd not finished
-ERR wotd not finished
</pre>
</pre>
== Hinweise zur Umsetzung ==
=== Nicht-blockierende Verbindungen ===
Jede Verbindung eines Clients zum Server erzeugt einen neuen <code>Thread</code>, der für die Kommunikation mit diesem Client zuständig ist. Um über eine spezifische Verbindung eine Nachricht zu empfangen, müssen daher die IP und Portnummer der Verbindung angegeben werden. Diese werden als Parameter immer einer der Methoden übergeben, die für die Verarbeitung von eingehenden Nachrichten zuständig sind. Sobald eine Nachricht eintrifft, sorgt die Server-Klasse dafür, dass die entsprechende <code>process*</code> Methode aufgerufen wird.
Wird etwa eine neue Verbindung von einem Client aufgebaut, dann wird <code>processNewConnection(String pClientIP, int pClientPort)</code> aufgerufen. Hier könnte der Server dann eine Antwort an den Client senden:
<syntaxhighlight lang="java">
@Override
public void processNewConnection( String pClientIP, int pClientPort ) {
    // Verarbeite die neue Verbindung (z.B. letzten Spielstand wiederherstellen, ...)
    send(pClientIP, pClientPort, "+OK welcome to wordle");
}
</syntaxhighlight>
=== Verbindungsspezifische Daten speichern ===
Der Server muss Daten pro Client speichern können (z.B. Spielstände). Clients können anhand der IP plus Portnummer identifiziert werden. Es müssen also abhängig von einem Schlüssel (IP+Port) Werte gespeichert werden. Eine Datenstruktur, die das erlaubt, kennen wir schon: {{Java API|java.util.HashMap||Hashtabellen}}.
=== Datenpersistenz  ===
Damit der Server Daten auch nach einem Verbindungsabbruch wiederherstellen kann, muss er sie dauerhaft speichern. Dazu können wir die Datenbank nutzen, um die Zustände abhängig von IP und Portnummer abzulegen.


== Dokumentationen ==
== Dokumentationen ==
Zeile 107: Zeile 130:


{| {{prettytable}}
{| {{prettytable}}
|+ Tabelle <code>words</code>
! id !! word
! id !! word
|-
|-
Zeile 114: Zeile 138:
|-
|-
| ... || ...
| ... || ...
}}
|}
 
=== Die Klasse Server ===
 
Über die Klasse Server ist es möglich, eigene Serverdienste anzubieten, so dass Clients Verbindungen gemäß dem TCP/IP-Protokoll hierzu aufbauen können. Nachrichten werden grundsätzlich zeilenweise verarbeitet, d. h., beim Senden einer Zeichenkette wird ein Zeilentrenner ergänzt und beim Empfangen wird er entfernt.
 
Verbindungsaufbau, Nachrichtenempfang und Verbindungsende geschehen nebenläufig. Durch Überschreiben der entsprechenden Methoden kann der Server auf diese Ereignisse reagieren.
 
Eine Fehlerbehandlung ist in dieser Klasse aus Gründen der Vereinfachung nicht vorgesehen.
 
{{Rahmen|
<code>Server(int pPortNr)</code><br />
Nach dem Aufruf dieses Konstruktors bietet ein Server seinen Dienst über die angegebene Portnummer an. Clients können sich nun mit dem Server verbinden.
 
<code>void closeConnection(String pClientIP, int pClientPort)</code><br />
Unter der Voraussetzung, dass eine Verbindung mit dem angegebenen Client existiert, wird diese beendet. Der Server sendet sich die Nachricht processClosedConnection.
 
<code>void processClosedConnection(String pClientIP, int pClientPort)</code><br />
Diese Methode ohne Anweisungen wird aufgerufen, bevor der Server die Verbindung zu dem in der Parameterliste spezifizierten Client schließt. Durch das Überschreiben in Unterklassen kann auf die Schließung der Verbindung zum angegebenen Client reagiert werden.
 
<code>void processMessage(String pClientIP, int pClientPort, String pMessage)</code><br />
Der Client mit der angegebenen IP und der angegebenen Portnummer hat dem Server eine Nachricht gesendet. Dieser ruft daraufhin diese Methode ohne Anweisungen auf. Durch das Überschreiben in Unterklassen kann auf diese Nachricht des angegebenen Client reagiert werden.
 
<code>void processNewConnection(String pClientIP, int pClientPort)</code><br />
Der Client mit der angegebenen IP-Adresse und der angegebenen Portnummer hat eine Verbindung zum Server aufgebaut. Der Server hat daraufhin diese Methode aufgerufen, die in dieser Klasse keine Anweisungen enthält. Durch das Überschreiben in Unterklassen kann auf diesen Neuaufbau einer Verbindung von dem angegebenen Client zum Server reagiert werden.
 
<code>void send(String pClientIP, int pClientPort, String pMessage)</code><br />
Wenn eine Verbindung zum angegebenen Client besteht, dann wird diesem Client die angegebene Nachricht - um einen Zeilentrenner erweitert - gesendet.
 
<code>void sendToAll(String pMessage)</code><br />
Die angegebene Nachricht wird - um einen Zeilentrenner erweitert - an alle verbundenen Clients gesendet.
 
<code>void close()</code><br />
Alle bestehenden Verbindungen werden getrennt. Der Server kann nicht mehr verwendet werden.}}
8.581

Bearbeitungen

Navigationsmenü