mirror of
https://github.com/dalbodeule/chibot-chzzk-bot.git
synced 2025-08-08 05:11:12 +00:00
add WebSocket timers
- EventDispatcher, TimerEvent add.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package space.mori.chzzk_bot.webserver
|
||||
|
||||
import io.ktor.http.*
|
||||
import io.ktor.serialization.kotlinx.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.engine.*
|
||||
@@ -12,9 +13,18 @@ import io.ktor.server.routing.*
|
||||
import io.ktor.server.websocket.*
|
||||
import kotlinx.serialization.json.Json
|
||||
import space.mori.chzzk_bot.webserver.routes.apiRoutes
|
||||
import space.mori.chzzk_bot.webserver.routes.wsTimerRoutes
|
||||
import java.time.Duration
|
||||
|
||||
val server = embeddedServer(Netty, port = 8080) {
|
||||
install(WebSockets)
|
||||
install(WebSockets) {
|
||||
pingPeriod = Duration.ofSeconds(15)
|
||||
timeout = Duration.ofSeconds(15)
|
||||
maxFrameSize = Long.MAX_VALUE
|
||||
masking = false
|
||||
contentConverter = KotlinxWebsocketSerializationConverter(Json)
|
||||
}
|
||||
|
||||
install(ContentNegotiation) {
|
||||
json(Json {
|
||||
prettyPrint = true
|
||||
@@ -27,6 +37,7 @@ val server = embeddedServer(Netty, port = 8080) {
|
||||
}
|
||||
routing {
|
||||
apiRoutes()
|
||||
wsTimerRoutes()
|
||||
swaggerUI("swagger-ui/index.html", "openapi/documentation.yaml") {
|
||||
options {
|
||||
version = "1.1.0"
|
||||
|
@@ -0,0 +1,76 @@
|
||||
package space.mori.chzzk_bot.webserver.routes
|
||||
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.websocket.*
|
||||
import io.ktor.websocket.*
|
||||
import kotlinx.coroutines.channels.ClosedReceiveChannelException
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.mori.chzzk_bot.common.events.Event
|
||||
import space.mori.chzzk_bot.common.events.TimerType
|
||||
import space.mori.chzzk_bot.common.services.UserService
|
||||
import space.mori.chzzk_bot.common.events.EventDispatcher
|
||||
import space.mori.chzzk_bot.common.events.EventHandler
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
fun Routing.wsTimerRoutes() {
|
||||
val sessions = ConcurrentHashMap<String, WebSocketServerSession>()
|
||||
|
||||
webSocket("/timer/{uid}") {
|
||||
val uid = call.parameters["uid"]
|
||||
val user = uid?.let { UserService.getUser(it) }
|
||||
if (uid == null) {
|
||||
close(CloseReason(CloseReason.Codes.CANNOT_ACCEPT, "Invalid UID"))
|
||||
return@webSocket
|
||||
}
|
||||
if (user == null) {
|
||||
close(CloseReason(CloseReason.Codes.CANNOT_ACCEPT, "Invalid UID"))
|
||||
return@webSocket
|
||||
}
|
||||
|
||||
sessions[uid] = this
|
||||
|
||||
try {
|
||||
for (frame in incoming) {
|
||||
when(frame) {
|
||||
is Frame.Text -> {
|
||||
|
||||
}
|
||||
is Frame.Ping -> send(Frame.Pong(frame.data))
|
||||
else -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(_: ClosedReceiveChannelException) {
|
||||
|
||||
} finally {
|
||||
sessions.remove(uid)
|
||||
}
|
||||
}
|
||||
|
||||
run {
|
||||
val dispatcher = EventDispatcher
|
||||
|
||||
dispatcher.register(TimerEvent::class.java, object : EventHandler<TimerEvent> {
|
||||
override suspend fun handle(event: TimerEvent) {
|
||||
sessions[event.uid]?.sendSerialized(TimerResponse(event.type, event.time ?: ""))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
enum class TimerType {
|
||||
UPTIME, TIMER
|
||||
}
|
||||
|
||||
class TimerEvent(
|
||||
val uid: String,
|
||||
val type: TimerType,
|
||||
val time: String?
|
||||
): Event
|
||||
|
||||
@Serializable
|
||||
data class TimerResponse(
|
||||
val type: TimerType,
|
||||
val time: String?
|
||||
)
|
Reference in New Issue
Block a user