websocket
- 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
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