首页 > 解决方案 > Kotlin 协程 - Ktor 服务器 WebSocket

问题描述

我制作了一个 kotlin-ktor 应用程序,我想要实现的是它是模块化的,任何时候应用程序内的任何管道都可以从源代码中删除而不会破坏任何功能。所以我决定我想将一个 websocket 实现移动到单独的类

但是我遇到了一个问题,即 lambda 表达式中的协程立即终止。 链接-github问题

有人可以告诉我有关协程设置的信息,以及如何在没有此类问题的情况下仍将其保持为模块化

工作 ktor websocket


fun Application.socketModule() = runBlocking {

   // other declarations
    ......

    routing {
        val sessionService = SocketSessionService()
        webSocket("/home") {
            val chatSession = call.sessions.get<ChatSession>()
            println("request session: $chatSession")

            if (chatSession == null) {
                close(CloseReason(CloseReason.Codes.VIOLATED_POLICY, "empty Session"))
                return@webSocket
            }
            send(Frame.Text("connected to server"))
            sessionService.addLiveSocket(chatSession.id, this)
            sessionService.checkLiveSocket()
        }

        thread(start = true, name = "socket-monitor") {
            launch {
                sessionService.checkLiveSocket()
            }
        }
    }
}

kotlin-ktor 自动关闭网络套接字

下面的代码自动关闭套接字

插座模块

class WebSocketServer {

    fun createWebSocket(root: String, routing: Routing) {
        println("creating web socket server")
        routing.installSocketRoute(root)
    }

    private fun Routing.installSocketRoute(root: String) {
        val base            = "/message/so"
        val socketsWeb      = SocketSessionService()

        webSocket("$root$base/{type}") {

            call.parameters["type"] ?: throw Exception("missing type")
            val session = call.sessions.get<ChatSession>()

            if (session == null) {
                println( "WEB-SOCKET:: client session is null" )
                close(CloseReason(CloseReason.Codes.VIOLATED_POLICY, "No Session"))
                return@webSocket
            }

            socketsWeb.addLiveSocket(session.id, this)

            thread(start= true, name = "thread-live-socket") {
                launch {
                    socketsWeb.checkLiveSocket()
                }
            }
        }
    }
}

应用模块

fun Application.socketModule() = runBlocking {
   // other delcarations
   .....
    install(Sessions) {
        cookie<ChatSession>("SESSION")
    }

    intercept(ApplicationCallPipeline.Features) {
        if (call.sessions.get<ChatSession>() == null) {
            val sessionID = generateNonce()
            println("generated Session: $sessionID")
            call.sessions.set(ChatSession(sessionID))
        }
    }

    routing {
        webSocketServer.createWebSocket("/home", this)
   }
}

我很不明白为什么协程insdie webSocket lamda完成了。有人可以向我展示其他/正确的方法吗?

标签: kotlinkotlin-coroutinesktor

解决方案


推荐阅读