I have a Ktor application with Netty engine, that ...
# ktor
s
I have a Ktor application with Netty engine, that connects to another server’s websocket using HttpClient with OkHttp engine. Periodically, I get a “Ping timeout” exception:
Copy code
Disconnected from server
java.io.IOException: Ping timeout
    at io.ktor.websocket.DefaultWebSocketSessionImpl$runOrCancelPinger$newPinger$1.invokeSuspend(DefaultWebSocketSession.kt:293)
...
    at io.ktor.websocket.PingPongKt$pinger$1.invokeSuspend(PingPong.kt:96)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
...
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
...
    at io.ktor.server.netty.EventLoopGroupProxy$Companion.create$lambda$1$lambda$0(NettyApplicationEngine.kt:291)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:833)
But ping interval is not configured on either OkHttp or client’s WebSocketSession. I assume they both are zeroes, why do I have the ping timeouts? A side question: If I configure ping interval on both OkHttp engine and client’s WebSocketSession, will it do two series of pings?
j
I am not able to answer your first question but I can help for the side one: yes, you will have two series of pings. The client will send a ping, the server will respond with pong. And when the server pings, then the client responds with pong. You could see this as redundant but it depends on your usage, one thing to know is when one of the ends pings the other one, only the one that sent the ping is able to tell if the connection is still alive. This means you can have one of the ends which will never be able to tell if the connection is stale or not. For example, imagine you have a server that sends multiple messages per minute, while the client only listens to them. If the client never sends pings and the connection is interrupted, it will never be able to tell, it will just wait endlessly. If, along the messages, the server sends pings, it will be able to tell the connection is interrupted, but the client will never know. Note that sending a message doesn't count as a ping, because it needs an answer to acknowledge the ping has been received. So, here, what I would do is the following: • Send regular pings from the client, at a frequency suiting your needs. If you want to know as soon as possible when the connection is stale, send a ping every 5 seconds with a short timeout. • If your server can tolerate sending multiple messages without a consumer on the other end, send a ping at long intervals like a minute or more. • If your server doesn't tolerate that, send pings at a higher frequency with a short timeout. Note that if you cannot tolerate ANY missing messages, you can make your client send a pong for any message received. The server will send the next message only when it receives the pong. Yes, you can send a pong without receiving a ping first.
e
Hey @Johann Pardanaud, it looks like a bug. Could you log a report in YT? I will take a look
j
What part are you talking about? 🤔
e
about having default ping timeout without getting it configured
j
sorry I'm lost, where am I saying this? 😅
e
Oh, sorry. I mean the original message from @Sergey Aldoukhov
👍 1
s
Also @Johann Pardanaud I totally understand that both server and client send pings to each other. My second question is not about that. It is about OkHttp and Ktor HttpClient having two different ping interval settings that can be configured differently. If I have both at a value > 0, would my client ping at both intervals? If so, that would be an API design deficiency…
j
Oooh, sorry I did not understand 😅 From my what I read in the documentation, the interval of the HttpClient is ignored when you use OkHttp. If you define 10s in HttpClient and 20s in OkHttp, only the 20s interval will be used.
👍 1
139 Views