# WEBSocket + KTOR

**URL:** <https://discuss.kotlinlang.org/t/websocket-ktor/30485>\
**Category:** Support\
**Created:** [June 16, 2025, 10:05pm UTC](https://discuss.kotlinlang.org/t/websocket-ktor/30485 "2025-06-16T22:05:10Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![lorrain.nicolas.nl](https://avatars.discourse-cdn.com/v4/letter/l/c77e96/32.png) [@lorrain.nicolas.nl](https://discuss.kotlinlang.org/u/lorrain.nicolas.nl)\
**Post date:** [June 16, 2025, 10:05pm UTC](https://discuss.kotlinlang.org/t/websocket-ktor/30485/1 "2025-06-16T22:05:10Z")

</div>

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

```auto
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

    }
}

```

---

<div class="post-metadata">

**Author:** ![Skater901](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/skater901/32/10163_2.png) [@Skater901](https://discuss.kotlinlang.org/u/Skater901)\
**Post date:** [June 17, 2025, 7:22am UTC](https://discuss.kotlinlang.org/t/websocket-ktor/30485/2 "2025-06-17T07:22:05Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![lorrain.nicolas.nl](https://avatars.discourse-cdn.com/v4/letter/l/c77e96/32.png) [@lorrain.nicolas.nl](https://discuss.kotlinlang.org/u/lorrain.nicolas.nl)\
**Post date:** [June 17, 2025, 7:52am UTC](https://discuss.kotlinlang.org/t/websocket-ktor/30485/3 "2025-06-17T07:52:56Z")

</div>

> [@lorrain.nicolas.nl](#):
>
> `incoming`

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

---

<div class="post-metadata">

**Author:** ![jean.chalard](https://avatars.discourse-cdn.com/v4/letter/j/b487fb/32.png) [@jean.chalard](https://discuss.kotlinlang.org/u/jean.chalard)\
**Post date:** [June 21, 2025, 3:35am UTC](https://discuss.kotlinlang.org/t/websocket-ktor/30485/4 "2025-06-21T03:35:50Z")

</div>

If the `finally` block is not called, it will essentially always be because your `try{}` block never exits. It needs to either return or throw.

I am not familiar with ktor either, but I don’t see where your `consumeEach` block would exit. Maybe `incoming#consumeEach` is supposed to throw ? Barring that, on `Frame.Close` your code just prints and continues to loop, and it also does nothing for any other event that’s not text. I’d expect some return somewhere, maybe in the handling of `Frame.Close`.
