ktorio / ktorio/ktor

websocket

Open
#4,939 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
14.5k
Forks
1.3k
Avg merge
2d 13h
Merged PRs (30d)
49

Description

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 with ktor.

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 (or call 20minutes after), so the webSocket is close after a long time? How can I prevent this memory leak? and to be sure that after 3minute offline the webSocket will be remove from my server please

I Have setup the ping pong like this

```

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

}
```

and this is my socket

```

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

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

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@webSocket
}

val sessionId = decodedJWT.id?.let {
runCatching { UUID.fromString(it) }.getOrNull()
} ?: run {
close(CloseReason(CloseReason.Codes.VIOLATED_POLICY, "Invalid or missing sessionId (jti)"))
return@webSocket
}

logger.info("$userId is connected")

try {
println("tototot $userId start")
incoming.consumeEach {
when (it) {

is Frame.Text -> {
val text = it.readText()
println("tototot $userId Received: $text")
}
is Frame.Close -> {
println("tototot $userId WebSocket closed by server with reason: ${it.readReason()}")
}
is Frame.Ping -> {
println("tototot $userId ping: $it")
}
is Frame.Pong -> {
println("tototot $userId pong: $it")
} else -> {
println("tototot $userId else: $it")
}
}

}
} catch (e: Exception) {
println("tototot $userId error $e")
} finally {
println("tototot $userId finally remove")
}

println("tototot $userId end")
}
}

```

I have this log after turn off the wifi from my iphone at 09:23:00

09:22:57 -> tototot 59e0c2cf-d5b4-41f2-90a0-fb1f418e73fc start
09:42:57 -> tototot 59e0c2cf-d5b4-41f2-90a0-fb1f418e73fc finally remove
09:42:57 ->tototot 59e0c2cf-d5b4-41f2-90a0-fb1f418e73fc end

and on ios I have the following error after 10secondes offline when I try a ping

Optional(Error Domain=NSPOSIXErrorDomain Code=60 "Operation timed out" UserInfo={NSDescription=Operation timed out})

Contributor guide

Open the contributing guide

Research direction

Start with the WebSockets installation showing pingPeriod and timeout, then trace the webSocket("ws") handler and its incoming.consumeEach loop. Reproduce the iOS offline case and determine why the handler remains active after the reported timeout; done means the connection is removed within the intended interval and the behavior is covered by an appropriate test.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.