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