Projekt im Modul Frameworks, Dienste und Daten im Web im SS2022
Calvin Hinzer - [email protected]
Anton Zaitsev - [email protected]
Für das Modul Frameworks, Dienste und Daten im Web wurde als Projekt das Kartenspiel UNO in vereinfachter Form entwickelt und umgesetzt. Dabei wurde der Fokus auf eine in Microservices aufgeteilte ereignisgesteuerte Architektur gelegt.
Für das Spiel gibt es ein eigenes Kartendeck mit 108 Karten. Die Karten haben vier Farben (blau, grün, rot, gelb) und die Werte von neun bis null. Hinzu kommen drei Aktionskarten in jeder Farbe sowie acht schwarze Aktionskarten. Da jede Karte bis auf die Null und die schwarzen Aktionskarten doppelt sind, kommen am Ende 108 Karten zusammen.
Jeder Spieler erhält zu Beginn des Spiels sieben Karten auf die Hand. Anschließend werden reihum Karten abgelegt. Karten können dabei nur auf dieselbe Farbe oder Werte abgelegt werden. Aktionskarten haben dabei unterschiedliche Funktionen (Zwei ziehen, Aussetzen, Richtungswechsel und Vier ziehen, Farbwechsel). Gewonnen hat der Spieler, der alle Karten als erstes abgelegt hat.
Die einzelnen Microservices im Backend wurden mit dem serverseitigem Javascript Framework Node.js umgesetzt. Dieses ermöglicht, vor allem durch die Einbindung von externen NPM-Packages, eine schnelle und unkomplizierte Implementierung von Funktionalitäten. Die Kommunikaton zwischen den Services erfolgt durch die Anbindung eines RabbitMQ Brokers, wodurch ein asynchroner Austausch von Nachrichten, auch im Falle eines Serviceausfalls, stattfinden kann.
Da das Team bereits Erfahrung mit dem Umgang des Frameworks create-react-app
hatte, wurde entschieden die Javascript-Library React für das Frontend zu verwenden. Dabei war es wichtig schnell und einfach wiederverwendbare UI Komponenten zu erstellen und einzusetzen.
Der Austausch von Spieldaten zwischen dem Frontend und den jeweiligen Services wird über die Socket.io Bibliothek realisiert. Diese baut auf dem Websocket Protokoll auf und bietet erweiterte Funktionen, wie z.B. eine garantierte Fallback-Lösung auf HTTP-Polling oder eine automatische Reconnect-Funktion.
Damit die Anwendungen lokal entwickelt und getestet werden können, werden diese über Docker sowie Docker Compose verwaltet. Die Services können dadurch unabhängig zum darunterliegendem Entwicklungssystem gestartet werden und es treten keine Kompatibilitätsprobleme auf.
Die Anwendung wurde in vier Backend Services aufgeteilt, welche unabhängige Funktionen übernehmen:
Der game_service ist für die gesamte Verwaltung von Spielen verantwortlich. Über den Service können neue Spiele gestartet oder bereits erstellten Spielen beigetreten werden. Zudem speichert der Service alle für ein Spiel benötigten Daten.
Der player_service erstellt und speichert alle Spielerdaten. Außerdem kommuniziert dieser zwischen dem Frontend und dem authentication_service.
Alle Spieler authentifizieren sich über einen JWT-Token. Diese werden nur vom authentication_service generiert. Jeder andere Backend Service kann den generierten Token anschließend unabhängig verfizieren.
Die einem Spieler zur Verfügung stehen Spielkarten in der eigenen Hand werden vom rule_service überprüft. Ein Spieler kann nach erfolgreicher Überprüfung nur noch Karten spielen, die auch den Regeln nach spielbar wären.
Zu Beginn muss sich ein Spieler mit einem gewählten Spielernamen anmelden. Für diesen Aufruf wird eine REST-Schnittstelle auf dem player_service bereitsgestellt. Der player_service leitet den eingegebenen Namen an eine externe API weiter, welche eine einfache Obszönitätskontrolle durchführt. Nach erfolgreicher Überprüfung werden die Daten als asynchrone Nachricht über RabbitMQ als AMQP Broker an den authentication_service weitergeleitet. Dieser generiert einen JWT-Token und schickt anschließend eine AMQP Nachricht über den Broker an den player_service. Hervorzuheben ist hierbei, dass jeder der anderen Services die Nachricht ebenfalls empfangen kann, aber nicht auf die Nachrichten reagiert. Dem Spieler wird der eigene JWT-Token zurückgesendet und danach weiter zum eigenen Dashboard weitergeleitet.
Von dem Dashboard aus kann ein Spieler ein neues Spiel erstellen, oder aber einem bereits erstelltem Spiel über die gameId beitreten. Beide Aufrufe werden dabei von dem game_service als REST-Schnittstellen bereitsgestellt.
Bei der Verbindung zu einem Spiel stellt das Frontend eine über den JWT-Token authentifizierte Socket.io Verbindung zum game_service sowie zum rule_service her. Durch die auf dem Websocket Protokoll aufbauende Technologie kann eine Echtzeitkommunikation aufgebaut und alle im Spiel auftredenden Interaktionen über Events von den jeweiligen Services verarbeitet werden.
Folgende wesentliche AMQP und Socket.io Events werden dabei im gesamten System versendet:
AMQP:
newPlayer
playerToken
updateWinners
Socket.io:
player_joined
player_left
deck_size_updated
discard_pile_updated
disconnect_from_socket
played_card
get_hands
game_started
game_ended
disconnect
start_game
draw_card
play_card
join_game
check_hand
checked_hand
Im folgenden wird erläutert, wie das Projekt lokal gestartet werden kann.
Folgende Programme werden benötigt:
-
Docker inkl. Docker-Compose
https://www.docker.com/get-started/
-
Das Repository klonen
git clone https://github.com/antonztsv/FDDWSS22_HinzerZaitsev.git
-
In den Ordner wechseln
cd FDDWSS22_HinzerZaitsev
-
Skript ausführen um die .env.example Dateien in jedem Backend Service in .env umzubennenen
./copy-env.sh
oder manuell:
cp ./backend/authentication_service/.env.example ./backend/authentication_service/.env cp ./backend/game_service/.env.example ./backend/game_service/.env cp ./backend/player_service/.env.example ./backend/player_service/.env cp ./backend/rule_service/.env.example ./backend/rule_service/.env
-
Anwendungen mit docker-compose starten
docker-compose up -d --build
Nach dem Starten der einzelnen Services kann es bis zu zehn Sekunden dauern, bis das Frontend sowie der RabbitMQ Service vollständig gestartet sind.
Das Frontend kann über http://localhost:3000
aufgerufen werden.
- Eingabe Spielername
- Erstellung eines neuen Spiels
- Beitritt des Spiels über einen anderen Browser (oder über Inkognito im gleichen Browser) über die gameId
- Spiel starten
- Spiel spielen
- Spiel beenden
Calvin Hinzer - [email protected]
Anton Zaitsev - [email protected]
Projekt Link: https://github.com/antonztsv/FDDWSS22_HinzerZaitsev