From 12af6604d6b134f23dac2270c4de4e482bd4a0e5 Mon Sep 17 00:00:00 2001 From: Fabrice Lecomte Date: Mon, 17 Mar 2025 22:45:15 +0100 Subject: [PATCH] create a websocket route to create and join a game --- .../GameCommandRouteWebSocket.kt | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/eventDemo/adapter/interfaceLayer/GameCommandRouteWebSocket.kt b/src/main/kotlin/eventDemo/adapter/interfaceLayer/GameCommandRouteWebSocket.kt index 4e5b683..d82b78f 100644 --- a/src/main/kotlin/eventDemo/adapter/interfaceLayer/GameCommandRouteWebSocket.kt +++ b/src/main/kotlin/eventDemo/adapter/interfaceLayer/GameCommandRouteWebSocket.kt @@ -5,17 +5,15 @@ import eventDemo.business.entity.GameId import eventDemo.business.entity.Player import eventDemo.business.event.eventListener.PlayerNotificationEventListener import eventDemo.business.notification.Notification -import eventDemo.configuration.ktor.BadRequestException -import eventDemo.configuration.ktor.HttpErrorBadRequest import eventDemo.libs.fromFrameChannel import eventDemo.libs.toObjectChannel import io.github.oshai.kotlinlogging.withLoggingContext -import io.ktor.http.parameters import io.ktor.server.application.ApplicationCall import io.ktor.server.auth.authenticate import io.ktor.server.auth.jwt.JWTPrincipal import io.ktor.server.auth.principal import io.ktor.server.routing.Route +import io.ktor.server.websocket.DefaultWebSocketServerSession import io.ktor.server.websocket.webSocket import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope @@ -30,29 +28,41 @@ fun Route.gameWebSocket( commandHandler: GameCommandHandler, ) { authenticate { - webSocket("/game/{id}") { - val currentPlayer = call.getPlayer() - val gameId = - call.parameters["id"]?.let { GameId(UUID.fromString(it)) } - ?: throw BadRequestException(HttpErrorBadRequest("No ID fore the game")) - val outgoingFrameChannel: SendChannel = fromFrameChannel(outgoing) - withLoggingContext("currentPlayer" to currentPlayer.toString()) { - GlobalScope.launch { - commandHandler.handle( - currentPlayer, - gameId, - toObjectChannel(incoming), - outgoingFrameChannel, - ) - } - - playerNotificationListener.startListening( - { outgoingFrameChannel.trySendBlocking(it) }, - currentPlayer, - gameId, - ) - } + webSocket("/games/new") { + runWebSocket(GameId(), commandHandler, playerNotificationListener) } + + webSocket("/games/{id}") { + val gameId = GameId(UUID.fromString(call.parameters["id"]!!)) + runWebSocket(gameId, commandHandler, playerNotificationListener) + } + } +} + +@DelicateCoroutinesApi +private fun DefaultWebSocketServerSession.runWebSocket( + gameId: GameId, + commandHandler: GameCommandHandler, + playerNotificationListener: PlayerNotificationEventListener, +) { + val currentPlayer = call.getPlayer() + val outgoingFrameChannel: SendChannel = fromFrameChannel(outgoing) + withLoggingContext("currentPlayer" to currentPlayer.toString()) { + // TODO change GlobalScope + GlobalScope.launch { + commandHandler.handle( + currentPlayer, + gameId, + toObjectChannel(incoming), + outgoingFrameChannel, + ) + } + + playerNotificationListener.startListening( + { outgoingFrameChannel.trySendBlocking(it) }, + currentPlayer, + gameId, + ) } }