WEBSocket + KTOR

Hello everyone I have a small issue and I don’t know how to fix,

I have the following code to set up my WebSocket. I’m trying to build a chat, and I store my sockets in a repository so that when client1 sends a message to client2, I can notify client2 via their WebSocket if they are connected.

My problem is the following: if I turn off the internet on the mobile side for about 3 minutes, my socket is no longer active, probably because the ping/pong fails. However, the finally block is never called, so I never remove the socket from the repository. How can I prevent this memory leak? and to be sure that after 3minute offline the webSocket will be remove from my reposotory
Thank you in advance

fun Application.configureWebSocketRouting() {

    val webSocketRepository by inject<WebSocketRepositoryInterface>()
    val logger by inject<Logger>()

    routing {
       // webSocket("ws") {
        webSocketRaw("ws") {
            val token = call.request.queryParameters["token"]
            if (token == null) {
                close(CloseReason(CloseReason.Codes.VIOLATED_POLICY, "No Token"))
                return@webSocketRaw
            }

            val decodedJWT = try { JwtFactory.buildverifier().verify(token) }
            catch (e: Exception) {
                close(CloseReason(CloseReason.Codes.VIOLATED_POLICY, "Invalid Token: ${e.message}"))
                return@webSocketRaw
            }

            val userId: UUID = try { UUID.fromString(decodedJWT.getClaim(JwtClaimConstant.claimUserId).asString())  }
            catch (e: Exception) {
                close(CloseReason(CloseReason.Codes.VIOLATED_POLICY, "Invalid Token: ${e.message}"))
                return@webSocketRaw
            }

            val sessionId = decodedJWT.id?.let {
                runCatching { UUID.fromString(it) }.getOrNull()
            } ?: run {
                close(CloseReason(CloseReason.Codes.VIOLATED_POLICY, "Invalid or missing sessionId (jti)"))
                return@webSocketRaw
            }
            logger.info("$userId is connected")

            try {
                webSocketRepository.onJoin(userId, sessionId,this)
                incoming.consumeEach {
                    when (it) {
                        is Frame.Text -> {
                            val text = it.readText()
                            println("tototot Received: $text")
                        }
                        is Frame.Close -> {
                            println("tototot WebSocket closed by server with reason: ${it.readReason()}")
                        }
                        else -> {}
                    }


                }
            } catch (e: Exception) {
                println("tototot error $e")
             } finally {
                println("tototot finally remove")
                webSocketRepository.removeSocket(userId, this)
                logger.info("$userId not connected anymore")
            }
        }
    }
}

// configuration

fun Application.configureWebSocket(){
    install(WebSockets) {
        pingPeriod = Duration.ofSeconds(15)
        timeout = Duration.ofSeconds(30)
        maxFrameSize = kotlin.Long.MAX_VALUE
        masking = false

    }
}

Could you post a link to your project on GitHub or wherever you have it? This code snippet is not enough for me since I haven’t used websockets in KTOR yet, so there’s a lot of bits of your code that I don’t understand. For example, what is incoming? Where is it defined?

hello thank you :slight_smile:
What do you need to have ? :slight_smile:
incoming it provide by websocket to have access to message from websock it’s from ktor side