-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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})