https://kotlinlang.org logo
#ktor
Title
# ktor
v

Venkat

11/23/2023, 8:11 AM
Is there anyway to reuse the same TCP connection for multiple http requests in Ktor client? I'm using the CIO engine.
e

e5l

11/23/2023, 8:12 AM
Hey! It will be reused if you don’t specify
Connection: Close
and the requests are fit in keep alive timeout
a

andriyo

11/23/2023, 8:13 AM
not sure about CIO specifically but isn't it the whole point of Keep-Alive header?
i mean it's pretty much default behavior to keep the socket open
v

Venkat

11/23/2023, 8:35 AM
Copy code
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*

suspend fun main() {
    val client = HttpClient(CIO)
    client.get("<http://ktor.io/>")
    client.get("<http://ktor.io/>")
    client.get("<http://ktor.io/>")
}
This creates three TCP connections (one for each GET request).
@e5l do you have any idea how can I do all three GETs in the same TCP connection?
👀 1
a

andriyo

11/23/2023, 8:43 AM
maybe try to consume a response before doing another get()? not sure - I always trusted it to do the right thing - creating a TCP connection for each request to the same host:port would be wasteful
v

Venkat

11/23/2023, 8:47 AM
Copy code
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import io.ktor.client.statement.*

suspend fun main() {
    val client = HttpClient(CIO)
    val res1 = client.get("<http://ktor.io/>")
    println(res1.bodyAsText())
    val res2 = client.get("<http://ktor.io/>")
    println(res2.bodyAsText())
    val res3 = client.get("<http://ktor.io/>")
    println(res3.bodyAsText())
}
It doing the same. @Aleksei Tirman [JB] any idea, please?
a

Aleksei Tirman [JB]

11/23/2023, 9:02 AM
Unfortunately, I cannot make the CIO engine reuse the TCP connection. You can use the
OkHttp
engine where the connections are reused by default.
v

Venkat

11/23/2023, 9:31 AM
Thanks! Both OkHttp and Java engines reuse the same TCP stream.
e

e5l

11/23/2023, 9:31 AM
@Aleksei Tirman [JB], could you log an issue for CIO?
v

Venkat

11/23/2023, 9:33 AM
I can create an issue with Wireshark logs, where do you want to create it? on the GitHub issue page?
e

e5l

11/23/2023, 9:33 AM
YT would be great
a

Aleksei Tirman [JB]

11/23/2023, 9:33 AM
You can file it here.
👍 1
But OkHttp or Java engine creates a new TCP stream for every Http request when I fire them asynchronously.
Copy code
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.request.*
import kotlinx.coroutines.*

suspend fun main() {
    val scope = CoroutineScope(Dispatchers.IO)
    val client = HttpClient(OkHttp)
    val responseDeferred = (0..3).map { scope.async { client.get("<http://ktor.io/>") } }
    responseDeferred.awaitAll()
    scope.cancel()
    client.close()
}
In the above code it creates 4 TCP connections, @Aleksei Tirman [JB] do I need to wait for the response of the first request before firing the next one to reuse the same TCP?
a

Aleksei Tirman [JB]

11/23/2023, 12:46 PM
Yes.
a

andriyo

11/23/2023, 5:01 PM
I just googled some documentation on multiplexing and it appears that HTTPS is required (?) for HTTP/2 for Ktor - that might be the reason? it looks like it needs some song and dance between client and server for proper multiplexing. And just old school pipelining might not work if Ktor tries to parallelize calls. However if we tried to consume head-of-the line response, that should work as well. Maybe there is an issue indeed.
34 Views