为什么当请求尝试超出“Ktor HttpClient(CIO) maxConnectionsCount”或“maxConnectionsPerRoute”值时会发生请求超时

Why Request timeout occurs when a request is attempted beyond the "Ktor HttpClient(CIO) maxConnectionsCount" or "maxConnectionsPerRoute" value

提问人:newmanjoo 提问时间:11/8/2023 最后编辑:newmanjoo 更新时间:11/9/2023 访问量:41

问:

"KtorBase2.kt"
open class KtorBase2()
{
    private val _httpClient: HttpClient
    val httpClient get() = _httpClient

    init {
        _httpClient = createHttpClient()
    }

    private fun createHttpClient(): HttpClient {
        return HttpClient(CIO) {
            engine {
                // this: CIOEngineConfig
                // I don't know why Request timeout occurs when I try to request beyond the maxConnectionsCount or maxConnectionsPerRoute values.
                maxConnectionsCount = 12 // system default=1000
                endpoint {
                    // this: EndpointConfig
                    maxConnectionsPerRoute = 100 // system default=100
                    pipelineMaxSize = 20 // system default=20
                    keepAliveTime = 5000 // system default=5000
                    connectTimeout = 5000 // system default=5000
                    connectAttempts = 1 // system default=1
                }
            }
        }
    }
}

"HomeDataAccesss.kt"
{
    suspend fun getTestHtml(ktorBase2: KtorBase2) : String {
        val response: HttpResponse =  ktorBase2.httpClient.get("http://ap2.shinwonsoft.com/test/test.html") {
        }

        return response.body()
    }
}

"HomeViewModel.kt"
{
    fun reqTestHtml(ktorBase2: KtorBase2, testCountForManyRequest: Int) {
        viewModelScope.launch {
            val str = HomeDataAccess.getTestHtml(ktorBase2)
            Log.d(logTag, "### reqTestHtml::html=$str, testCountForManyRequest=$testCountForManyRequest")
        }
    }
}

"HomeFragment.kt"
class HomeFragment: Fragemnt {
    private var _testCountForManyRequest: Int = 0
    private val _testKtorForManyRequest: KtorBase2 = KtorBase2(URLProtocol.HTTP)

    ...

    private fun initViewEventListener() {
        binding.textHome.setOnClickListener {
            (it as TextView).text = "Home fragemnt: ${++_testCountForManyRequest}"

            _homeViewModel.reqTestHtml(_testKtorForManyRequest, _testCountForManyRequest)
        }
    }
}

"console log"
19:05:33.635 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=1
19:06:52.385 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=2
19:07:28.888 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=3
19:07:29.653 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=4
19:07:30.231 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=5
19:07:30.726 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=6
19:07:31.266 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=7
19:07:32.122 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=8
19:07:33.303 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=9
19:11:11.393 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=10
19:11:30.733 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=11
19:11:36.508 HE_HomeViewModel         D  ### reqTestHtml::html=test..., testCountForManyRequest=12
19:11:48.195 android.ha...mpl.ranchu  D  threadLoop: entering standby, frames: 2233440
--------- beginning of crash
19:11:50.138 StatusBarIconController  D  ignoring old pipeline callbacks, because the new mobile icons are enabled
19:11:50.167 AndroidRuntime           E  FATAL EXCEPTION: main
    Process: kr.co.heavyequipment, PID: 4914
    io.ktor.client.network.sockets.ConnectTimeoutException: Connect timeout has expired [url=http://ap2.shinwonsoft.com/test/test.html, connect_timeout=unknown ms]
    at io.ktor.client.plugins.HttpTimeoutKt.ConnectTimeoutException(HttpTimeout.kt:213)
    at io.ktor.client.plugins.HttpTimeoutKt.ConnectTimeoutException$default(HttpTimeout.kt:210)
    at io.ktor.client.engine.cio.Endpoint.getTimeoutException(Endpoint.kt:268)
    at io.ktor.client.engine.cio.Endpoint.connect(Endpoint.kt:257)
    at io.ktor.client.engine.cio.Endpoint.access$connect(Endpoint.kt:25)
    at io.ktor.client.engine.cio.Endpoint$connect$1.invokeSuspend(Unknown Source:15)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.internal.ScopeCoroutine.afterResume(Scopes.kt:32)
    at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:102)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
    at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@5f7479, Dispatchers.Main.immediate]
19:11:50.173 DropBoxManagerService    I  add tag=data_app_crash isTagEnabled=true flags=0x2
19:11:50.175 ActivityTaskManager      W    Force finishing activity kr.co.he/.ui.main.MainActivity

我不知道为什么当请求尝试超出“Ktor HttpClient(CIO) maxConnectionsCount”或“maxConnectionsPerRoute”值时会发生请求超时。

在 “Ktor::HttpClient::engine” 中设置的 “maxConnectionsCount=12” 数量之前,请求会成功,但第 13 个请求会发生超时错误。

如果设置“maxConnectionsCount=12, maxConnectionsPerRoute=10”,则在第 11 个请求时发生超时错误。

首席信息官是否以错误的方式使用它?我希望你能帮上忙。

(即使你无限增加最大值,也不会给Android终端带来负担吗?

Android 连接 最大 httpclient ktor

评论

0赞 Aleksei Tirman 11/9/2023
我无法重现您的确切问题。您可以通过属性安装插件以增加连接超时。HttpTimeoutconnectTimeoutMillis
0赞 newmanjoo 11/9/2023
我设置了“超时安装”,如下所示。我收到同样的错误。install(HttpTimeout) { if (isBuildConfigDebug) { // BuildConfig.DEBUG requestTimeoutMillis = 30_000L connectTimeoutMillis = 30_000L socketTimeoutMillis = 30_000L } else { requestTimeoutMillis = 10_000L connectTimeoutMillis = 10_000L socketTimeoutMillis = 10_000L } }
0赞 newmanjoo 11/9/2023
由于上述错误,我用 Apache5 进行了测试。使用 Apache5 而不是 CIO 尝试请求测试 3500 次时没有错误。
0赞 newmanjoo 11/9/2023
我的项目build.gradle(app);def ktor_version = '2.3.5' implementation(“io.ktor:ktor-client-core:$ktor_version”);implementation(“io.ktor:ktor-client-cio:$ktor_version”);implementation(“io.ktor:ktor-client-apache5:$ktor_version”);实现 (“io.ktor:ktor-client-java:$ktor_version”);Ktor序列化;implementation(“io.ktor:ktor-client-content-negotiation:$ktor_version”);implementation(“io.ktor:ktor-serialization-kotlinx-json:$ktor_version”);Ktor 身份验证;实现(“io.ktor:ktor-client-auth:$ktor_version”);
0赞 Aleksei Tirman 11/10/2023
您能否使用最小的独立代码片段提交问题 (youtrack.jetbrains.com/newIssue?project=KTOR) 以重现问题?

答: 暂无答案