summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw-client/build.gradle.kts10
-rw-r--r--sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt83
-rw-r--r--sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSocketConfig.kt1
-rw-r--r--sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt16
-rw-r--r--sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/sagas/Sagas.kt3
5 files changed, 55 insertions, 58 deletions
diff --git a/sw-client/build.gradle.kts b/sw-client/build.gradle.kts
index 1f4996bc..0c21cd36 100644
--- a/sw-client/build.gradle.kts
+++ b/sw-client/build.gradle.kts
@@ -3,7 +3,7 @@ plugins {
id("org.jlleitschuh.gradle.ktlint")
}
-val krossbowVersion = "0.4.1"
+val krossbowVersion = "0.10.2"
kotlin {
jvm()
@@ -15,7 +15,7 @@ kotlin {
dependencies {
api(project(":sw-common-model"))
implementation(kotlin("stdlib-common"))
- implementation("org.hildan.krossbow:krossbow-client-metadata:$krossbowVersion")
+ api("org.hildan.krossbow:krossbow-stomp-kxserialization:$krossbowVersion")
}
}
val commonTest by getting {
@@ -27,7 +27,7 @@ kotlin {
val jvmMain by getting {
dependencies {
implementation(kotlin("stdlib-jdk8"))
- implementation("org.hildan.krossbow:krossbow-client-jvm:$krossbowVersion")
+ api("org.hildan.krossbow:krossbow-stomp-kxserialization-jvm:$krossbowVersion")
}
}
val jvmTest by getting {
@@ -39,8 +39,8 @@ kotlin {
val jsMain by getting {
dependencies {
implementation(kotlin("stdlib-js"))
- implementation("org.hildan.krossbow:krossbow-client-js:$krossbowVersion")
- implementation(npm("webstomp-client")) // required by krossbow
+ api("org.hildan.krossbow:krossbow-stomp-kxserialization-js:$krossbowVersion")
+ implementation(npm("text-encoding", "0.7.0")) // required by krossbow, because required by kotlinx-io
}
}
val jsTest by getting {
diff --git a/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt b/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt
index 691a3f0a..4acbccd9 100644
--- a/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt
+++ b/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt
@@ -1,10 +1,16 @@
package org.luxons.sevenwonders.client
-import kotlinx.coroutines.channels.ReceiveChannel
-import kotlinx.coroutines.channels.map
-import org.hildan.krossbow.client.KrossbowClient
-import org.hildan.krossbow.client.KrossbowSession
-import org.hildan.krossbow.client.KrossbowSubscription
+import kotlinx.serialization.ImplicitReflectionSerializer
+import kotlinx.serialization.list
+import kotlinx.serialization.serializer
+import org.hildan.krossbow.stomp.StompClient
+import org.hildan.krossbow.stomp.StompSubscription
+import org.hildan.krossbow.stomp.conversions.kxserialization.StompSessionWithKxSerialization
+import org.hildan.krossbow.stomp.conversions.kxserialization.convertAndSend
+import org.hildan.krossbow.stomp.conversions.kxserialization.subscribe
+import org.hildan.krossbow.stomp.conversions.kxserialization.withJsonConversions
+import org.hildan.krossbow.stomp.sendEmptyMsg
+import org.hildan.krossbow.stomp.subscribeEmptyMsg
import org.luxons.sevenwonders.model.CustomizableSettings
import org.luxons.sevenwonders.model.GameState
import org.luxons.sevenwonders.model.PlayerTurnInfo
@@ -21,50 +27,41 @@ import org.luxons.sevenwonders.model.cards.PreparedCard
class SevenWondersClient {
- private val stompClient = KrossbowClient()
+ private val stompClient = StompClient()
- suspend fun connect(serverUrl: String): SevenWondersSession {
- val session = stompClient.connect("$serverUrl$SEVEN_WONDERS_WS_ENDPOINT")
+ suspend fun connect(serverHost: String): SevenWondersSession {
+ val session = stompClient.connect("ws://$serverHost$SEVEN_WONDERS_WS_ENDPOINT").withJsonConversions()
return SevenWondersSession(session)
}
}
-suspend inline fun <reified T : Any, reified U : Any> KrossbowSession.request(
+@OptIn(ImplicitReflectionSerializer::class)
+suspend inline fun <reified T : Any, reified U : Any> StompSessionWithKxSerialization.request(
sendDestination: String,
receiveDestination: String,
payload: T? = null
): U {
val sub = subscribe<U>(receiveDestination)
- send(sendDestination, payload)
+ convertAndSend(sendDestination, payload)
val msg = sub.messages.receive()
sub.unsubscribe()
- return msg.payload
+ return msg
}
-data class SevenWondersSubscription<T : Any>(
- val messages: ReceiveChannel<T>,
- val unsubscribe: suspend () -> Unit
-)
-
-private fun <T : Any> KrossbowSubscription<T>.ignoreHeaders() = SevenWondersSubscription(
- messages = messages.map { it.payload },
- unsubscribe = { unsubscribe() }
-)
-
-class SevenWondersSession(private val stompSession: KrossbowSession) {
+class SevenWondersSession(private val stompSession: StompSessionWithKxSerialization) {
suspend fun disconnect() = stompSession.disconnect()
- suspend fun watchErrors(): KrossbowSubscription<ErrorDTO> =
- stompSession.subscribe("/user/queue/errors")
+ suspend fun watchErrors(): StompSubscription<ErrorDTO> =
+ stompSession.subscribe("/user/queue/errors", ErrorDTO.serializer())
suspend fun chooseName(displayName: String): PlayerDTO {
val action = ChooseNameAction(displayName)
return stompSession.request("/app/chooseName", "/user/queue/nameChoice", action)
}
- suspend fun watchGames(): SevenWondersSubscription<Array<LobbyDTO>> =
- stompSession.subscribe<Array<LobbyDTO>>("/topic/games").ignoreHeaders()
+ suspend fun watchGames(): StompSubscription<List<LobbyDTO>> =
+ stompSession.subscribe("/topic/games", LobbyDTO.serializer().list)
suspend fun createGame(gameName: String): LobbyDTO {
val action = CreateGameAction(gameName)
@@ -77,40 +74,40 @@ class SevenWondersSession(private val stompSession: KrossbowSession) {
}
suspend fun leaveGame() {
- stompSession.send("/app/lobby/leave")
+ stompSession.sendEmptyMsg("/app/lobby/leave")
}
suspend fun reorderPlayers(players: List<String>) {
- stompSession.send("/app/lobby/reorderPlayers", ReorderPlayersAction(players))
+ stompSession.convertAndSend("/app/lobby/reorderPlayers", ReorderPlayersAction(players), ReorderPlayersAction.serializer())
}
suspend fun updateSettings(settings: CustomizableSettings) {
- stompSession.send("/app/lobby/reorderPlayers", UpdateSettingsAction(settings))
+ stompSession.convertAndSend("/app/lobby/reorderPlayers", UpdateSettingsAction(settings), UpdateSettingsAction.serializer())
}
- suspend fun watchLobbyUpdates(gameId: Long): SevenWondersSubscription<LobbyDTO> =
- stompSession.subscribe<LobbyDTO>("/topic/lobby/$gameId/updated").ignoreHeaders()
+ suspend fun watchLobbyUpdates(gameId: Long): StompSubscription<LobbyDTO> =
+ stompSession.subscribe("/topic/lobby/$gameId/updated", LobbyDTO.serializer())
- suspend fun watchGameStart(gameId: Long): SevenWondersSubscription<Unit> =
- stompSession.subscribe<Unit>("/topic/lobby/$gameId/started").ignoreHeaders()
+ suspend fun watchGameStart(gameId: Long): StompSubscription<Unit> =
+ stompSession.subscribeEmptyMsg("/topic/lobby/$gameId/started")
suspend fun startGame() {
- stompSession.send("/app/lobby/startGame")
+ stompSession.sendEmptyMsg("/app/lobby/startGame")
}
- suspend fun watchPlayerReady(gameId: Long): SevenWondersSubscription<String> =
- stompSession.subscribe<String>("/topic/game/$gameId/playerReady").ignoreHeaders()
+ suspend fun watchPlayerReady(gameId: Long): StompSubscription<String> =
+ stompSession.subscribe("/topic/game/$gameId/playerReady", String.serializer())
- suspend fun watchTableUpdates(gameId: Long): SevenWondersSubscription<GameState> =
- stompSession.subscribe<GameState>("/topic/game/$gameId/tableUpdates").ignoreHeaders()
+ suspend fun watchTableUpdates(gameId: Long): StompSubscription<GameState> =
+ stompSession.subscribe("/topic/game/$gameId/tableUpdates", GameState.serializer())
- suspend fun watchPreparedCards(gameId: Long): SevenWondersSubscription<PreparedCard> =
- stompSession.subscribe<PreparedCard>("/topic/game/$gameId/prepared").ignoreHeaders()
+ suspend fun watchPreparedCards(gameId: Long): StompSubscription<PreparedCard> =
+ stompSession.subscribe("/topic/game/$gameId/prepared", PreparedCard.serializer())
- suspend fun watchTurns(): SevenWondersSubscription<PlayerTurnInfo> =
- stompSession.subscribe<PlayerTurnInfo>("/user/queue/game/turn").ignoreHeaders()
+ suspend fun watchTurns(): StompSubscription<PlayerTurnInfo> =
+ stompSession.subscribe("/user/queue/game/turn", PlayerTurnInfo.serializer())
suspend fun sayReady() {
- stompSession.send("/app/game/sayReady")
+ stompSession.sendEmptyMsg("/app/game/sayReady")
}
}
diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSocketConfig.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSocketConfig.kt
index 72312b70..8bff83da 100644
--- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSocketConfig.kt
+++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSocketConfig.kt
@@ -30,7 +30,6 @@ class WebSocketConfig @Autowired constructor(private val topicSubscriptionInterc
registry.addEndpoint(SEVEN_WONDERS_WS_ENDPOINT)
.setHandshakeHandler(handshakeHandler())
.setAllowedOrigins("*") // to allow any client to use the API
- .withSockJS()
}
@Bean
diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt
index 7b996680..ab947609 100644
--- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt
+++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt
@@ -67,7 +67,7 @@ class SevenWondersTest {
session2.joinGame(lobby.id)
val outsiderSession = newPlayer("Outsider")
- val (started) = outsiderSession.watchGameStart(lobby.id)
+ val started = outsiderSession.watchGameStart(lobby.id).messages
ownerSession.startGame()
val nothing = withTimeoutOrNull(30) { started.receive() }
@@ -94,7 +94,7 @@ class SevenWondersTest {
fun createGame_seenByConnectedPlayers() {
runBlocking {
val otherSession = newPlayer("OtherPlayer")
- val (games) = otherSession.watchGames()
+ val games = otherSession.watchGames().messages
var receivedLobbies = withTimeout(500) { games.receive() }
assertNotNull(receivedLobbies)
@@ -126,18 +126,18 @@ class SevenWondersTest {
val session3 = newPlayer("Player3")
session3.joinGame(lobby.id)
- val (gameStart1) = session1.watchGameStart(lobby.id)
- val (gameStart2) = session2.watchGameStart(lobby.id)
- val (gameStart3) = session3.watchGameStart(lobby.id)
+ val gameStart1 = session1.watchGameStart(lobby.id).messages
+ val gameStart2 = session2.watchGameStart(lobby.id).messages
+ val gameStart3 = session3.watchGameStart(lobby.id).messages
session1.startGame()
withTimeout(500) { gameStart1.receive() }
withTimeout(500) { gameStart2.receive() }
withTimeout(500) { gameStart3.receive() }
- val (turns1) = session1.watchTurns()
- val (turns2) = session2.watchTurns()
- val (turns3) = session3.watchTurns()
+ val turns1 = session1.watchTurns().messages
+ val turns2 = session2.watchTurns().messages
+ val turns3 = session3.watchTurns().messages
session1.sayReady()
session2.sayReady()
session3.sayReady()
diff --git a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/sagas/Sagas.kt b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/sagas/Sagas.kt
index 837c4db6..728a7d2f 100644
--- a/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/sagas/Sagas.kt
+++ b/sw-ui-kt/src/main/kotlin/org/luxons/sevenwonders/ui/redux/sagas/Sagas.kt
@@ -13,7 +13,8 @@ typealias SwSagaContext = SagaContext<SwState, RAction, WrapperAction>
suspend fun SwSagaContext.rootSaga() {
val action = next<RequestChooseName>()
- val session = SevenWondersClient().connect("http://localhost:8000")
+ val session = SevenWondersClient().connect("localhost:8000")
+ console.info("Connected to Seven Wonders web socket API")
coroutineScope {
launch { gameBrowserSaga(session) }
bgstack15