Add server & shared module and remove the serveur from the client app.
This commit is contained in:
parent
fa87f05be6
commit
3419afbe59
47 changed files with 233 additions and 530 deletions
|
|
@ -0,0 +1,7 @@
|
|||
package com.pixelized.server.lwa
|
||||
|
||||
import com.pixelized.server.lwa.server.LocalServer
|
||||
|
||||
fun main() {
|
||||
LocalServer().create().start()
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.pixelized.server.lwa.extention
|
||||
|
||||
import com.pixelized.server.lwa.protocol.Message
|
||||
import io.ktor.websocket.Frame
|
||||
import io.ktor.websocket.readText
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.encodeToJsonElement
|
||||
|
||||
fun Json.decodeFromFrame(frame: Frame.Text): Message {
|
||||
val json = frame.readText()
|
||||
return decodeFromString<Message>(json)
|
||||
}
|
||||
|
||||
fun Json.encodeToFrame(message: Message): Frame {
|
||||
val json = encodeToJsonElement(message)
|
||||
return Frame.Text(text = json.toString())
|
||||
}
|
||||
101
server/src/main/kotlin/com/pixelized/server/lwa/server/Server.kt
Normal file
101
server/src/main/kotlin/com/pixelized/server/lwa/server/Server.kt
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
package com.pixelized.server.lwa.server
|
||||
|
||||
import com.pixelized.server.lwa.SERVER_PORT
|
||||
import com.pixelized.server.lwa.extention.decodeFromFrame
|
||||
import io.ktor.server.application.install
|
||||
import io.ktor.server.engine.EmbeddedServer
|
||||
import io.ktor.server.engine.embeddedServer
|
||||
import io.ktor.server.netty.Netty
|
||||
import io.ktor.server.netty.NettyApplicationEngine
|
||||
import io.ktor.server.routing.routing
|
||||
import io.ktor.server.websocket.DefaultWebSocketServerSession
|
||||
import io.ktor.server.websocket.WebSockets
|
||||
import io.ktor.server.websocket.pingPeriod
|
||||
import io.ktor.server.websocket.timeout
|
||||
import io.ktor.server.websocket.webSocket
|
||||
import io.ktor.websocket.Frame
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.channels.consumeEach
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
// https://ktor.io/docs/server-websockets.html#handle-multiple-session
|
||||
typealias Server = EmbeddedServer<NettyApplicationEngine, NettyApplicationEngine.Configuration>
|
||||
|
||||
class LocalServer {
|
||||
private var server: Server? = null
|
||||
private val scope = CoroutineScope(Dispatchers.IO)
|
||||
private var networkJob: Job? = null
|
||||
private val outgoingMessageBuffer = MutableSharedFlow<Frame>()
|
||||
|
||||
fun create(): LocalServer {
|
||||
server = build {
|
||||
println("Server launched")
|
||||
|
||||
val job = launch {
|
||||
// send local message to the clients
|
||||
outgoingMessageBuffer.collect { frame ->
|
||||
send(frame)
|
||||
}
|
||||
}
|
||||
runCatching {
|
||||
// watching for clients incoming message
|
||||
incoming.consumeEach { frame ->
|
||||
if (frame is Frame.Text) {
|
||||
val message = Json.decodeFromFrame(frame = frame)
|
||||
println(message)
|
||||
// broadcast to clients the message
|
||||
outgoingMessageBuffer.emit(frame)
|
||||
}
|
||||
}
|
||||
}.onFailure { exception ->
|
||||
println("WebSocket exception: ${exception.localizedMessage}")
|
||||
}.also {
|
||||
job.cancel()
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun start() {
|
||||
runBlocking {
|
||||
try {
|
||||
server?.start(wait = true)
|
||||
} catch (exception: Exception) {
|
||||
// TODO
|
||||
println("WebSocket exception: ${exception.localizedMessage}")
|
||||
} finally {
|
||||
println("Server close")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun build(
|
||||
port: Int = SERVER_PORT,
|
||||
handler: suspend DefaultWebSocketServerSession.() -> Unit
|
||||
): EmbeddedServer<NettyApplicationEngine, NettyApplicationEngine.Configuration> {
|
||||
return embeddedServer(
|
||||
factory = Netty,
|
||||
port = port,
|
||||
module = {
|
||||
install(WebSockets) {
|
||||
pingPeriod = 15.seconds
|
||||
timeout = 15.seconds
|
||||
maxFrameSize = Long.MAX_VALUE
|
||||
masking = false
|
||||
}
|
||||
routing {
|
||||
webSocket(
|
||||
path = "/ws",
|
||||
handler = handler,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue