Files
event-demo/src/main/kotlin/eventDemo/app/command/GameCommandRouteWebSocket.kt

50 lines
1.6 KiB
Kotlin

package eventDemo.app.command
import eventDemo.app.entity.Player
import eventDemo.app.eventListener.PlayerNotificationEventListener
import eventDemo.app.notification.Notification
import eventDemo.libs.fromFrameChannel
import eventDemo.libs.toObjectChannel
import io.github.oshai.kotlinlogging.withLoggingContext
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.webSocket
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.launch
@DelicateCoroutinesApi
fun Route.gameWebSocket(
playerNotificationListener: PlayerNotificationEventListener,
commandHandler: GameCommandHandler,
) {
authenticate {
webSocket("/game") {
val currentPlayer = call.getPlayer()
val outgoingFrameChannel: SendChannel<Notification> = fromFrameChannel(outgoing)
withLoggingContext("currentPlayer" to currentPlayer.toString()) {
GlobalScope.launch {
commandHandler.handle(
currentPlayer,
toObjectChannel(incoming),
outgoingFrameChannel,
)
}
playerNotificationListener.startListening(outgoingFrameChannel, currentPlayer)
}
}
}
}
private fun ApplicationCall.getPlayer() =
principal<JWTPrincipal>()!!.run {
Player(
id = payload.getClaim("playerid").asString(),
name = payload.getClaim("username").asString(),
)
}