Skip to content

客户端引擎

Ktor HTTP 客户端 是多平台的,可在 JVM、AndroidJavaScript(包括 WebAssembly)以及 Native 目标平台运行。每个平台都需要一个特定的引擎来处理网络请求。例如,对于 JVM 应用程序,可以使用 ApacheJetty;对于 Android,可以使用 OkHttpAndroid;对于面向 Kotlin/Native 的桌面应用程序,可以使用 Curl。每个引擎在特性和配置上略有不同,因此你可以选择最符合你的平台和用例需求的引擎。

支持的平台

下表列出了每个引擎支持的平台

EnginePlatforms
Apache5JVM
JavaJVM
JettyJVM
AndroidJVM, Android
OkHttpJVM, Android
DarwinNative
WinHttpNative
CurlNative
CIOJVM, Android, Native, JavaScript, WasmJs
JsJavaScript

支持的 Android/Java 版本

面向 JVM 或同时面向 JVM 和 Android 的客户端引擎支持以下 Android/Java 版本:

EngineAndroid versionJava version
Apache58+
Java11+
Jetty11+
CIO7.0+ *8+
Android1.x+8+
OkHttp5.0+8+

* 要在旧版 Android 上使用 CIO 引擎,你需要启用 Java 8 API desugaring

添加引擎依赖项

除了 ktor-client-core artifact 之外,Ktor 客户端还需要为特定的引擎添加依赖项。每个支持的平台都有一组可用的引擎,详见相应部分:

Ktor 提供带有 -jvm-js 等后缀的平台特有构件。例如,ktor-client-cio-jvm。依赖项解析因构建工具而异。Gradle 可以解析适用于给定平台的构件,而 Maven 不支持此功能。这意味着对于 Maven,你需要手动指定平台后缀。

指定引擎

要使用特定引擎,请将引擎类作为实参传递给 HttpClient 构造函数。以下示例创建了一个使用 CIO 引擎的客户端:

kotlin
import io.ktor.client.*
import io.ktor.client.engine.cio.*

val client = HttpClient(CIO)

默认引擎

如果你省略引擎实参,客户端将根据构建脚本中的依赖项自动选择一个引擎。

kotlin
import io.ktor.client.*

val client = HttpClient()

这在多平台项目中特别有用。例如,对于同时面向 Android 和 iOS 的项目,你可以将 Android 依赖项添加到 androidMain 源代码集,并将 Darwin 依赖项添加到 iosMain 源代码集。在 HttpClient 创建时,将会在运行时选择合适的引擎。

配置引擎

要配置引擎,请使用 engine {} 函数。所有引擎都可以使用 HttpClientEngineConfig 中的通用选项进行配置:

kotlin
HttpClient() {
    engine {
        // this: HttpClientEngineConfig
        threadsCount = 4
        pipelining = true
    }
}

在接下来的部分中,你将了解如何为不同平台配置特定的引擎。

JVM

JVM 目标平台支持 Apache5JavaJetty 引擎。

Apache5

Apache5 引擎支持 HTTP/1.1 和 HTTP/2,其中 HTTP/2 默认启用。这是新项目推荐使用的基于 Apache 的引擎。

旧版 Apache 引擎依赖于已弃用的 Apache HttpClient 4。它仅为向后兼容性保留。对于所有新项目,请使用 Apache5

  1. 添加 ktor-client-apache5 依赖项:

    Kotlin
    Groovy
    XML
  2. Apache5 类作为实参传递给 HttpClient 构造函数:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.apache5.*
    
    val client = HttpClient(Apache5)
  3. 使用 engine {} 代码块访问并设置 Apache5EngineConfig 中的属性:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.apache5.*
    import org.apache.hc.core5.http.*
    
    val client = HttpClient(Apache5) {
        engine {
            // this: Apache5EngineConfig
            followRedirects = true
            socketTimeout = 10_000
            connectTimeout = 10_000
            connectionRequestTimeout = 20_000
            customizeClient {
                // this: HttpAsyncClientBuilder
                setProxy(HttpHost("127.0.0.1", 8080))
                // ...
            }
            customizeRequest {
                // this: RequestConfig.Builder
            }
        }
    }

Java

Java 引擎使用 Java 11 中引入的 Java HTTP Client。要使用它,请按照以下步骤操作:

  1. 添加 ktor-client-java 依赖项:

    Kotlin
    Groovy
    XML
  2. Java 类作为实参传递给 HttpClient 构造函数:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.java.*
    
    val client = HttpClient(Java)
  3. 要配置引擎,请在 engine {} 代码块中设置 JavaHttpConfig 中的属性:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.*
    import io.ktor.client.engine.java.*
    
    val client = HttpClient(Java) {
        engine {
            // this: JavaHttpConfig
            threadsCount = 8
            pipelining = true
            proxy = ProxyBuilder.http("http://proxy-server.com/")
            protocolVersion = java.net.http.HttpClient.Version.HTTP_2
        }
    }

Jetty

Jetty 引擎仅支持 HTTP/2,可按以下方式配置:

  1. 添加 ktor-client-jetty-jakarta 依赖项:

    Kotlin
    Groovy
    XML
  2. Jetty 类作为实参传递给 HttpClient 构造函数:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.jetty.jakarta.*
    
    val client = HttpClient(Jetty)
  3. 要配置引擎,请在 engine {} 代码块中设置 JettyEngineConfig 中的属性:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.jetty.jakarta.*
    import org.eclipse.jetty.util.ssl.SslContextFactory
    
    val client = HttpClient(Jetty) {
        engine {
            // this: JettyEngineConfig
            sslContextFactory = SslContextFactory.Client()
            clientCacheSize = 12
        }
    }

JVM 和 Android

在本节中,我们将介绍适用于 JVM/Android 的引擎及其配置。

Android

Android 引擎面向 Android 平台,可按以下方式配置:

  1. 添加 ktor-client-android 依赖项:

    Kotlin
    Groovy
    XML
  2. Android 类作为实参传递给 HttpClient 构造函数:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.android.*
    
    val client = HttpClient(Android)
  3. 要配置引擎,请在 engine {} 代码块中设置 AndroidEngineConfig 中的属性:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.android.*
    import java.net.Proxy
    import java.net.InetSocketAddress
    
    val client = HttpClient(Android) {
        engine {
            // this: AndroidEngineConfig
            connectTimeout = 100_000
            socketTimeout = 100_000
            proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("localhost", 8080))
        }
    }

OkHttp

基于 OkHttp 的 OkHttp 引擎可按以下方式配置:

  1. 添加 ktor-client-okhttp 依赖项:

    Kotlin
    Groovy
    XML
  2. OkHttp 类作为实参传递给 HttpClient 构造函数:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.okhttp.*
    
    val client = HttpClient(OkHttp)
  3. 要配置引擎,请在 engine {} 代码块中设置 OkHttpConfig 中的属性:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.okhttp.*
    
    val client = HttpClient(OkHttp) {
        engine {
            // this: OkHttpConfig
            config {
                // this: OkHttpClient.Builder
                followRedirects(true)
                // ...
            }
            addInterceptor(interceptor)
            addNetworkInterceptor(interceptor)
    
            preconfigured = okHttpClientInstance
        }
    }

Native

Ktor 为 Kotlin/Native 目标平台提供了 DarwinWinHttpCurl 引擎。

在 Kotlin/Native 项目中使用 Ktor 需要新的内存管理器,该管理器从 Kotlin 1.7.20 开始默认启用。

Darwin

Darwin 引擎面向基于 Darwin 的操作系统,例如 macOS、iOS、tvOS 和 watchOS。它在底层使用 NSURLSession。要使用 Darwin 引擎,请按照以下步骤操作:

  1. 添加 ktor-client-darwin 依赖项:

    Kotlin
    Groovy
    XML
  2. Darwin 类作为实参传递给 HttpClient 构造函数:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.darwin.*
    
    val client = HttpClient(Darwin)
  3. engine {} 代码块中使用 DarwinClientEngineConfig 配置引擎。例如,你可以使用 configureRequest 来自定义请求,或使用 configureSession 来自定义会话:

    kotlin
    val client = HttpClient(Darwin) {
        engine {
            configureRequest {
                setAllowsCellularAccess(true)
            }
        }
    }

    有关完整示例,请参见 client-engine-darwin

WinHttp

WinHttp 引擎面向基于 Windows 的操作系统。 要使用 WinHttp 引擎,请按照以下步骤操作:

  1. 添加 ktor-client-winhttp 依赖项:

    Kotlin
    Groovy
    XML
  2. WinHttp 类作为实参传递给 HttpClient 构造函数:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.winhttp.*
    
    val client = HttpClient(WinHttp)
  3. engine {} 代码块中使用 WinHttpClientEngineConfig 配置引擎。例如,你可以使用 protocolVersion 属性更改 HTTP 版本:

    kotlin
    val client = HttpClient(WinHttp) {
        engine {
            protocolVersion = HttpProtocolVersion.HTTP_1_1
        }
    }

    有关完整示例,请参见 client-engine-winhttp

Curl

对于桌面平台,Ktor 提供了 Curl 引擎。它支持 linuxX64linuxArm64macosX64macosArm64mingwX64。要使用 Curl 引擎,请按照以下步骤操作:

  1. 添加 ktor-client-curl 依赖项:

    Kotlin
    Groovy
    XML
  2. Curl 类作为实参传递给 HttpClient 构造函数:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.curl.*
    
    val client = HttpClient(Curl)
  3. engine {} 代码块中使用 CurlClientEngineConfig 配置引擎。 例如,为测试目的禁用 SSL 验证:

    kotlin
    val client = HttpClient(Curl) {
        engine {
            sslVerify = false
        }
    }

    有关完整示例,请参见 client-engine-curl

JVM、Android、Native、JS 和 WasmJs

CIO

CIO 引擎是一个完全异步的基于协程的引擎,可在 JVM、Android、Native、JavaScript 和 WebAssembly JavaScript (WasmJs) 平台使用。它目前仅支持 HTTP/1.x。要使用它,请按照以下步骤操作:

  1. 添加 ktor-client-cio 依赖项:

    Kotlin
    Groovy
    XML
  2. CIO 类作为实参传递给 HttpClient 构造函数:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.cio.*
    
    val client = HttpClient(CIO)
  3. engine {} 代码块中使用 CIOEngineConfig 配置引擎:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.cio.*
    import io.ktor.network.tls.*
    
    val client = HttpClient(CIO) {
        engine {
            // this: CIOEngineConfig
            maxConnectionsCount = 1000
            endpoint {
                // this: EndpointConfig
                maxConnectionsPerRoute = 100
                pipelineMaxSize = 20
                keepAliveTime = 5000
                connectTimeout = 5000
                connectAttempts = 5
            }
            https {
                // this: TLSConfigBuilder
                serverName = "api.ktor.io"
                cipherSuites = CIOCipherSuites.SupportedSuites
                trustManager = myCustomTrustManager
                random = mySecureRandom
                addKeyStore(myKeyStore, myKeyStorePassword)
            }
        }
    }

JavaScript

Js 引擎可用于 JavaScript 项目。它对浏览器应用程序使用 fetch API,对 Node.js 使用 node-fetch。要使用它,请按照以下步骤操作:

  1. 添加 ktor-client-js 依赖项:

    Kotlin
    Groovy
    XML
  2. Js 类作为实参传递给 HttpClient 构造函数:

    kotlin
    import io.ktor.client.*
    import io.ktor.client.engine.js.*
    
    val client = HttpClient(Js)

    你也可以调用 JsClient() 函数来获取 Js 引擎单例:

    kotlin
    import io.ktor.client.engine.js.*
    
    val client = JsClient()

有关完整示例,请参见 client-engine-js

限制

HTTP/2 和 WebSockets

并非所有引擎都支持 HTTP/2 协议。如果引擎支持 HTTP/2,你可以在引擎的配置中启用它。例如,使用 Java 引擎。

下表显示了特定引擎是否支持 HTTP/2 和 WebSockets

EngineHTTP/2WebSockets
Apache5✅️✖️
Java✅️
Jetty✖️
CIO✖️
Android✖️✖️
OkHttp
Js
Darwin
WinHttp
Curl

安全性

SSL 必须按引擎配置。每个引擎都提供自己的 SSL 配置选项。

代理支持

一些引擎不支持代理。有关完整列表,请参见代理文档

日志记录

Logging 插件根据目标平台提供不同的日志记录器类型。

超时

HttpTimeout 插件对某些引擎有一些限制。有关完整列表,请参见超时限制

示例:如何在多平台移动项目配置引擎

在构建多平台项目时,你可以使用期望与实际声明来为每个目标平台选择和配置引擎。这允许你在公共代码中共享大部分客户端配置,同时在平台代码中应用引擎特有的选项。我们将使用在创建跨平台移动应用程序教程中创建的项目来演示如何实现这一点:

    1. 打开 shared/src/commonMain/kotlin/com/example/kmmktor/Platform.kt 文件,并添加一个顶层 httpClient() 函数,该函数接受配置代码块并返回一个 HttpClient

      kotlin
      expect fun httpClient(config: HttpClientConfig<*>.() -> Unit = {}): HttpClient
    2. 打开 shared/src/androidMain/kotlin/com/example/kmmktor/Platform.kt,并为 Android 模块添加 httpClient() 函数的实际声明:

      kotlin
      import io.ktor.client.*
      import io.ktor.client.engine.okhttp.*
      import java.util.concurrent.TimeUnit
      
      actual fun httpClient(config: HttpClientConfig<*>.() -> Unit) = HttpClient(OkHttp) {
         config(this)
      
         engine { 
            config {
               retryOnConnectionFailure(true)
               connectTimeout(0, TimeUnit.SECONDS)
            }
         }
      }

      此示例展示了如何配置 OkHttp 引擎,但你也可以使用其他支持 Android 的引擎。

    3. 打开 shared/src/iosMain/kotlin/com/example/kmmktor/Platform.kt,并为 iOS 模块添加 httpClient() 函数的实际声明:

      kotlin
      import io.ktor.client.*
      import io.ktor.client.engine.darwin.*
      
      actual fun httpClient(config: HttpClientConfig<*>.() -> Unit) = HttpClient(Darwin) {
         config(this)
         engine {
            configureRequest {
               setAllowsCellularAccess(true)
            }
         }
      }

      现在你可以在共享代码中调用 httpClient(),而无需担心使用哪个引擎。

    4. 要在共享代码中使用客户端,请打开 shared/src/commonMain/kotlin/com/example/kmmktor/Greeting.kt,并将 HttpClient() 构造函数替换为 httpClient() 函数调用:

      kotlin
      private val client = httpClient()