Skip to content

websocket #4939

@lorrainNicolas

Description

@lorrainNicolas

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions