Is there anyway to reuse the same TCP connection f...
# ktor
v
Is there anyway to reuse the same TCP connection for multiple http requests in Ktor client? I'm using the CIO engine.
e
Hey! It will be reused if you don’t specify
Connection: Close
and the requests are fit in keep alive timeout
a
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
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
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
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
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
Thanks! Both OkHttp and Java engines reuse the same TCP stream.
e
@Aleksei Tirman [JB], could you log an issue for CIO?
v
I can create an issue with Wireshark logs, where do you want to create it? on the GitHub issue page?
e
YT would be great
a
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
Yes.
a
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.
107 Views