Changes for page Basisprojekt
Last modified by mgrawunder on 2025/09/09 08:42
From 38.1 to 38.2
From 53.1 to 54.1
From version 38.2
edited by mgrawunder
on 2025/09/03 10:18
on 2025/09/03 10:18
Change comment:
There is no comment for this version
To version 53.1
edited by mgrawunder
on 2025/09/09 08:17
on 2025/09/09 08:17
Change comment:
Uploaded new attachment "1757398628416-879.png", version {1}
Summary
-
Page properties (1 modified, 0 added, 0 removed)
-
Attachments (0 modified, 25 added, 0 removed)
- 1756888245896-845.png
- 1756888279902-777.png
- 1756888428042-802.png
- 1756888762381-912.png
- 1756888929507-312.png
- 1756889440395-856.png
- 1756889472103-847.png
- 1756889590500-656.png
- 1756889795622-530.png
- 1756889917681-650.png
- 1756889979252-910.png
- 1756890010118-149.png
- 1756890800817-370.png
- 1756890924024-346.png
- 1756890958794-603.png
- 1756891019715-621.png
- 1756891125969-748.png
- 1756891180516-843.png
- 1756891216134-578.png
- 1756891254830-647.png
- 1756891375095-158.png
- 1756891512330-186.png
- 1756891551794-161.png
- 1756891617399-232.png
- 1757398628416-879.png
Details
- Page properties
-
- Content
-
... ... @@ -11,9 +11,12 @@ 11 11 12 12 == Clone == 13 13 14 +Achtung! In dem Screenshot wird das globale Basisprojekt verwendet. Für jede Grupp 15 + 14 14 [[image:1755245971657-468.png]] 15 15 16 16 19 + 17 17 [[image:1755245980026-164.png]] 18 18 19 19 Auf anderen Branch wechseln (hier development) ... ... @@ -192,5 +192,227 @@ 192 192 [[image:1756887488020-376.png||height="642" width="904"]] 193 193 194 194 198 +Jetzt kann man entweder in IntelliJ 195 195 196 - 200 +[[image:1756888245896-845.png||height="347" width="620"]] 201 + 202 +oder im Terminal (z.B. auch in IntelliJ) 203 + 204 +[[image:1756888279902-777.png||height="637" width="1053"]] 205 + 206 +Wobei hier auch clean compile reichen würde. 207 + 208 +**ACHTUNG! Falls maven Problem macht, kann das auch an einer falschen Java-Version im System liegen (siehe auch [[FAQ>>doc:.Basisprojekt FAQ.WebHome]])** 209 + 210 +Es werden durch den Aufruf neue Inhalte generiert (bzw. die alten überschrieben). 211 + 212 +[[image:1756888428042-802.png||height="538" width="1077"]] 213 + 214 +Hinweis: Niemals Änderungen unterhalb des target-Ordners machen. Das wird von Maven bei clean gelöscht. 215 + 216 +=== Wie bekommt man dann aber nun die Funktionalität rein? === 217 + 218 +Für jeden Endpunkt (also aktuell lobbies und users) werden drei Interfaces/Klassen erzeugt: 219 + 220 +* *Api (z.B, LobbiesApi): Beschreibung der REST-Methoden, vor allem auch das Mapping von z.B. /lobbies/join auf die Methode lobbyJoin(String) 221 +* ((( 222 +*ApiController implements *Api (Für Spring) (z.B. LobbiesApiController) 223 +))) 224 +* ((( 225 +*ApiDelegate (z.B. LobbiesApiDelegate): Macht die eigentliche Arbeit und muss** im eigenen Code-Bereich** erweitert werden! 226 +))) 227 + 228 + 229 + 230 +== Schritt 2: Erweiterung auf Server-Seite == 231 + 232 +Da es schon Funktionen für die Lobbies gibt, gibt es auch bereits eine Implementierung, die LobbiesApiDelegate überschreibt 233 + 234 +[[image:1756888762381-912.png||height="48" width="789"]] 235 + 236 +Wenn man einen neuen Endpunkt definiert, muss man auch einen neuen Service definieren. (Hinweis: Der Service muss eine Spring Komponenten sein, damit sie in den Spring Context aufgenommen wird). 237 + 238 +In der Klasse muss man dann die neue Methode lobbyList aus der API überschreiben. 239 + 240 +[[image:1756888929507-312.png||height="156" width="1161"]] 241 + 242 +Dabei wird folgendes gemacht: 243 + 244 +1. Es wird ein Rückgabeobjekt vom Typ Liste erzeugt 245 +1. Es wird über alles Lobbies auf dem Server gegangen (lobbyManagement.getLobbies()) 246 +1. Da der Client u.U. nicht die vollständigen Informationen über die Lobbies bekommen soll, gibt es zwei unterschiedliche Klassen: ServerLobby und LobbyDTO. 247 +1. Die Foreach-Schleife sorgt dafür, dass in das Rückgabeobjekt nur die LobbyDTOs eingefügt werden. 248 +1. Dafür wird eine Funktion mit dem Namen lobbyMapping verwendet 249 +1. Schließlich wird am Ende gesagt, dass alles ok ist und eine Antwort ResponseEntity.ok mit dem Rückgabeobjekt (lobbies) gesendet. 250 + 251 +**Anmerkung**: Das Basisprojekt ist aktuell so eingerichtet, dass Spring Exceptions auffängt und entsprechend an den Client leitet. Diese findet in der Klasse GlobalExceptionHandler statt 252 + 253 +Auf Server-Seite fehlt jetzt noch die Methode getLobbies im LobbyManagement 254 + 255 +[[image:1756889590500-656.png||height="81" width="518"]] 256 + 257 + 258 +=== LobbyMapping === 259 + 260 +Da man relativ oft Server-Objekt in DTO umwandeln muss gibt es im Basisprojekt MapStruct. Damit muss man nur die DTO-Klasse anlegen (i.d.R. über OpenAPI!!) 261 + 262 +Also z.B. 263 + 264 +[[image:1756889440395-856.png]] 265 + 266 +und definiert ein Interface mit einer Annotation 267 + 268 +[[image:1756889472103-847.png]] 269 + 270 +und damit kann man die Funktion aufrufen. Hinweis: Der Mapper ist im LobbyService über die Spring Dependency Injection gebunden. 271 + 272 +== Schritt 3: Erweiterung auf Client-Seite (Java) == 273 + 274 +Hinweis: Das Beispiel bezieht sich hier auf eine Client mit Java. Für andere Clients wie Angular ist das Vorgehen anders. 275 + 276 +Auf der Client-Seite wird die komplette Kommunikation mit dem Server in der generierten Klasse DefaultApi gekapselt. 277 + 278 +[[image:1756889795622-530.png]] 279 + 280 +Dort gibt es eine neue Methode lobbyList. Die sorgt dafür, dass der REST-Aufruf auf die Server-Seite geht und liefert das passende Objekt List<LobbyDTO> zurück 281 + 282 +Im Client gibt es auch eine Klasse LobbyService. Dort ist die DefaultApi Klasse über Dependency Injection gebunden. 283 + 284 +[[image:1756889917681-650.png]] 285 + 286 +Dort kann man nun eine neue Methode getLobbies() integrieren: 287 + 288 +[[image:1756889979252-910.png]] 289 + 290 +Und das Ganze dann z.B. im MainMenuPresenter verwenden: 291 + 292 +[[image:1756890010118-149.png||height="116" width="972"]] 293 + 294 +Anmerkung: Obwohl DefaultApi alle Funktionen zum Server kapselt, sollte man im Client spezifische Services für bestimmte Bereich haben, die diese Klasse verwenden. Das führt zu einer besseren Trennung von Funktionalitäten im Code. 295 + 296 + 297 += Kommunikation: Server ~-~-> Client (WebSockets) = 298 + 299 +[[image:1756890800817-370.png||height="604" width="1121"]] 300 + 301 +Da man mit REST nicht Nachrichten vom Server an den Client schicken kann, werden im Basisprojekt dafür WebSockets verwendet. 302 + 303 +Spring bietet eine native Unterstützung von WebSockets. Für eigene Funktionen kann man sich in die Kommunikation über die Serverklasse WebSocketHandler einklinken 304 + 305 + 306 +[[image:1756890924024-346.png||height="377" width="1092"]] 307 + 308 + 309 +Sobald sich jemand beim Server für WebSockets angemeldet hat wird von Spring ein org.springframework.web.socket.messaging.SessionConnectedEvent 310 +geworfen, welches in der folgenden Methode (im WebSocketHandler) aufgefangen wird 311 + 312 +[[image:1756890958794-603.png||height="373" width="1087"]] 313 + 314 +Die Methode ist Observer für das Event SessionConnectedEvent 315 + 316 +Der WebSocketServer kennt die Nutzer und erlaubt das Einloggen nur, wenn Login und Passwort stimmen (durch Spring Security) 317 + 318 +[[image:1756891019715-621.png]] 319 + 320 +1)Aus dem Event kann der Nutzer gelesen werden (der sollte nie leer sein) 321 + 322 +2) Dann wird sich aus dem Repository (später mehr) der Nutzer geholt, der durch den Namen identifiziert ist (z.B. „test1“) 323 + 324 +3) Schließlich werden allen anderen darüber informiert, dass ein neuer Nutzer da ist 325 + 326 +== STOMP == 327 + 328 +WebSockets haben kein Protokoll (wie z.B. http) 329 + 330 +Es können entweder binäre oder textuelle Daten verarbeitet werden (die jeweiligen Gegenstellen müssen das wissen!) 331 + 332 +Wenn man jetzt mehr als nur Text verschicken möchte, muss man sich überlegen, wie man Objekte z.B. mit JSON serialisiert (analog zu REST) 333 + 334 +STOMP: Streaming Text Oriented Messaging Protocol 335 + 336 +Definiert ein einfaches Protokoll, welches es erlaubt, sinnvoll über WebSockets zu kommunizieren 337 + 338 +Ist ein Teil von Spring 339 + 340 +Methoden sind z.B. CONNECT, SEND oder SUBSCRIBE 341 + 342 +STOMP arbeitet mit Topics 343 + 344 +Ein Client registriert (SUBSCRIBE) sich für bestimmte Ereignistypen 345 + 346 + 347 +§Wenn auf der Server-Seite dieser Typ veröffentlich wird dann wird dies an die jeweils interessierten Clients geschickt 348 + 349 +Publish/Subscribe-Pattern 350 + 351 +[[https:~~/~~/docs.spring.io/spring-framework/reference/web/websocket/stomp.html>>url:https://docs.spring.io/spring-framework/reference/web/websocket/stomp.html]] 352 + 353 + 354 +§Der Server definiert unterschiedliche Topics (je nach Modul) 355 + 356 +§Beim Nutzermanagement aktuell: 357 + 358 +§/topic/users/loggedIn: Es hat sich ein neuer Nutzer angemeldet 359 + 360 +§/topic/users/loggedOut: Ein Nutzer hat sich ausgeloggt 361 + 362 + 363 +[[image:1756891125969-748.png||height="317" width="726"]] 364 + 365 +§Topic-Namen sind Strings, sollte aber Aufbau von oben entsprechen 366 + 367 +§In der Lobby würde es stattdessen /topic/lobbies/* heißen 368 + 369 +== WebSockets: Versenden von Nachrichten == 370 + 371 +[[image:1756891180516-843.png||height="426" width="801"]] 372 + 373 +[[image:1756891216134-578.png||height="428" width="699"]] 374 + 375 +== Nachrichteninhalt == 376 + 377 +[[image:1756891254830-647.png||height="101" width="777"]] 378 + 379 +* message kann grundsätzlich alles sein, was serialisiert werden kann 380 +* Man könnte nun einfach die Java-Serialisierung verwenden (im alten Basisprojekt ist das auch so) 381 +* Das hat aber eine Reihe von Nachteilen 382 +** Der Empfänger muss dafür unbedingt auch ein Java-Client sein und er muss exakt dieselbe Klasse bei sich haben, damit der das Objekt wieder zurück in ein Java-Objekt umwandeln kann 383 +** Es gibt eine Reihe von Sicherheitsproblemen 384 +* Besser: Definiere ein gemeinsames Austauschformat, was viele verstehen ~-~-> Im Basisprojekt (und in vielen anderen Projekten auch) JSON verwenden 385 +* Insbesondere Web-Clients (JavaScript) bieten hervorragende Möglichkeiten, an JSON zu verarbeiten 386 +* Client und Server haben sich damit auf Format für den Austausch geeinigt 387 +** Topic: Strings 388 +** Message: JSON 389 + 390 +An den Clilent werden auch bei WebSockets nur DTOs verschickt! (userMapping) 391 + 392 +[[image:1756891375095-158.png||height="266" width="775"]] 393 + 394 +== Wie verbindet sich ein Client mit dem Server? == 395 + 396 +UserService bietet eine Methode zum Login an. Diese ruft nun aber keine REST-Endpunkt auf (da man sich sowieso bei JEDEM Aufruf authentifizieren muss, macht so ein Endpunkt kein Sinn). Stattdessen wird die Verbindung mit dem WebSocket hergestellt und dort Nama und Passwort überprüft. 397 + 398 +[[image:1756891512330-186.png||height="170" width="820"]] 399 + 400 +=== Auf Server Seite (WebSocketConnectionManager): === 401 + 402 +[[image:1756891551794-161.png||height="387" width="1019"]] 403 + 404 +1) Variablen definieren 405 + 406 +2) WebSocketClient erzeugen 407 + 408 +3) Daraus WebSocketStompClient machen 409 + 410 +4) Jackson als Mapper definieren (DTO-Object <-> JSON) 411 + 412 +=== [[image:1756891617399-232.png||height="289" width="1006"]] === 413 + 414 + 415 +1) Asynchron die Verbindung zum Server aufbauen 416 + 417 +2) Wenn erfolgreich in das Hauptmenü wechseln (showScene à später mehr) 418 + 419 +3) Über den Kontext ein Event pushen LoggedInEvent 420 + 421 +4) Jede Serververbindung hat eine Session
- 1756888245896-845.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +115.6 KB - Content
- 1756888279902-777.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +518.9 KB - Content
- 1756888428042-802.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +312.3 KB - Content
- 1756888762381-912.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +3.4 KB - Content
- 1756888929507-312.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +16.9 KB - Content
- 1756889440395-856.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +55.9 KB - Content
- 1756889472103-847.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +11.1 KB - Content
- 1756889590500-656.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +4.8 KB - Content
- 1756889795622-530.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +379.7 KB - Content
- 1756889917681-650.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +6.0 KB - Content
- 1756889979252-910.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +4.0 KB - Content
- 1756890010118-149.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +16.8 KB - Content
- 1756890800817-370.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +61.9 KB - Content
- 1756890924024-346.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +54.8 KB - Content
- 1756890958794-603.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +32.6 KB - Content
- 1756891019715-621.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +58.6 KB - Content
- 1756891125969-748.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +37.9 KB - Content
- 1756891180516-843.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +153.4 KB - Content
- 1756891216134-578.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +246.0 KB - Content
- 1756891254830-647.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +11.0 KB - Content
- 1756891375095-158.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +33.2 KB - Content
- 1756891512330-186.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +43.0 KB - Content
- 1756891551794-161.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +53.9 KB - Content
- 1756891617399-232.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +49.9 KB - Content
- 1757398628416-879.png
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.mgrawunder - Size
-
... ... @@ -1,0 +1,1 @@ 1 +16.4 KB - Content