客户端引擎
Ktor HTTP client 是多平台的,运行在 JVM、Android、JavaScript(包括 WebAssembly)以及 Native 目标平台上。每个平台都需要一个特定的引擎来处理网络请求。 例如,您可以在 JVM 应用程序中使用 Apache 或 Jetty;在 Android 中使用 OkHttp 或 Android;在针对 Kotlin/Native 的桌面应用程序中使用 Curl。每个引擎在功能和配置上略有不同,因此您可以选择最符合您的平台和用例需求的引擎。
受支持的平台
下表列出了各引擎支持的平台:
| 引擎 | 平台 |
|---|---|
Apache5 | JVM |
Java | JVM |
Jetty | JVM |
Android | JVM, Android |
OkHttp | JVM, Android |
Darwin | Native |
WinHttp | Native |
Curl | Native |
CIO | JVM, Android, Native, JavaScript, WasmJs |
Js | JavaScript |
受支持的 Android/Java 版本
针对 JVM 或同时针对 JVM 和 Android 的客户端引擎支持以下 Android/Java 版本:
| 引擎 | Android 版本 | Java 版本 |
|---|---|---|
Apache5 | 8+ | |
Java | 11+ | |
Jetty | 11+ | |
CIO | 7.0+ * | 8+ |
Android | 1.x+ | 8+ |
OkHttp | 5.0+ | 8+ |
* 要在较旧的 Android 版本上使用 CIO 引擎,您需要启用 Java 8 API 脱糖 (desugaring)。
添加引擎依赖项
除了 ktor-client-core 构件外,Ktor 客户端还需要特定引擎的依赖项。每个受支持平台都有一组可用的引擎,详见相应章节:
Ktor 提供了带有
-jvm或-js等后缀的平台专用构件。例如,ktor-client-cio-jvm。依赖项解析因构建工具而异。虽然 Gradle 会解析适用于给定平台的构件,但 Maven 不支持此功能。这意味着对于 Maven,您需要手动指定平台后缀。
指定引擎
要使用特定引擎,请将引擎类传递给 HttpClient 构造函数。以下示例创建了一个使用 CIO 引擎的客户端:
import io.ktor.client.*
import io.ktor.client.engine.cio.*
val client = HttpClient(CIO)默认引擎
如果省略引擎参数,客户端将根据构建脚本中的依赖项自动选择引擎。
import io.ktor.client.*
val client = HttpClient()这在多平台项目中尤其有用。例如,对于同时针对 Android 和 iOS 的项目,您可以将 Android 依赖项添加到 androidMain 源集中,并将 Darwin 依赖项添加到 iosMain 源集中。合适的引擎会在运行时创建 HttpClient 时被选中。
配置引擎
要配置引擎,请使用 engine {} 函数。所有引擎都可以使用 HttpClientEngineConfig 中的通用选项进行配置:
HttpClient() {
engine {
// this: HttpClientEngineConfig
threadsCount = 4
pipelining = true
}
}在接下来的章节中,您可以了解如何为不同平台配置特定的引擎。
JVM
JVM 目标支持 Apache5、Java 和 Jetty 引擎。
Apache5
Apache5 引擎同时支持 HTTP/1.1 和 HTTP/2,且默认启用 HTTP/2。这是针对新项目推荐的基于 Apache 的引擎。
较旧的
Apache引擎依赖于已弃用的 Apache HttpClient 4。保留它仅为了向后兼容。对于所有新项目,请使用Apache5。
添加
ktor-client-apache5依赖项:KotlinGroovyXML将
Apache5类作为参数传递给HttpClient构造函数:kotlinimport io.ktor.client.* import io.ktor.client.engine.apache5.* val client = HttpClient(Apache5)使用
engine {}块访问并设置Apache5EngineConfig中的属性:kotlinimport 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 // 配置 Apache5 ConnectionManager configureConnectionManager { setMaxConnPerRoute(1_000) setMaxConnTotal(2_000) } // 自定义底层 Apache 客户端的其他设置 customizeClient { // this: HttpAsyncClientBuilder setProxy(HttpHost("127.0.0.1", 8080)) // ... } // 自定义每个请求的设置 customizeRequest { // this: RequestConfig.Builder } } }- 使用
configureConnectionManager进行连接管理器设置,例如最大连接数。这会保留 Ktor 管理的引擎行为。 - 仅将
customizeClient用于与连接管理器无关的设置,例如代理、拦截器或日志记录。
- 使用
Java
Java 引擎使用 Java 11 中引入的 Java HTTP Client。要使用它,请按以下步骤操作:
添加
ktor-client-java依赖项:KotlinGroovyXML将 Java 类作为参数传递给
HttpClient构造函数:kotlinimport io.ktor.client.* import io.ktor.client.engine.java.* val client = HttpClient(Java)要配置引擎,在
engine {}块中设置JavaHttpConfig的属性:kotlinimport 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,可以按以下方式配置:
添加
ktor-client-jetty-jakarta依赖项:KotlinGroovyXML将
Jetty类作为参数传递给HttpClient构造函数:kotlinimport io.ktor.client.* import io.ktor.client.engine.jetty.jakarta.* val client = HttpClient(Jetty)要配置引擎,在
engine {}块中设置JettyEngineConfig的属性:kotlinimport 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 平台,可以按以下方式配置:
添加
ktor-client-android依赖项:KotlinGroovyXML将
Android类作为参数传递给HttpClient构造函数:kotlinimport io.ktor.client.* import io.ktor.client.engine.android.* val client = HttpClient(Android)要配置引擎,在
engine {}块中设置AndroidEngineConfig的属性:kotlinimport 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,可以按以下方式配置:
添加
ktor-client-okhttp依赖项:KotlinGroovyXML将
OkHttp类作为参数传递给HttpClient构造函数:kotlinimport io.ktor.client.* import io.ktor.client.engine.okhttp.* val client = HttpClient(OkHttp)要配置引擎,在
engine {}块中设置OkHttpConfig的属性:kotlinimport 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 duplexStreamingEnabled = true // 仅适用于 HTTP/2 连接 } }
Native
Ktor 为 Kotlin/Native 目标平台提供了 Darwin、WinHttp 和 Curl 引擎。
在 Kotlin/Native 项目中使用 Ktor 需要新内存管理器,从 Kotlin 1.7.20 开始默认启用。
Darwin
Darwin 引擎针对 基于 Darwin 的 操作系统,如 macOS、iOS、tvOS 和 watchOS。它在底层使用 NSURLSession。要使用 Darwin 引擎,请按以下步骤操作:
添加
ktor-client-darwin依赖项:KotlinGroovyXML将
Darwin类作为参数传递给HttpClient构造函数:kotlinimport io.ktor.client.* import io.ktor.client.engine.darwin.* val client = HttpClient(Darwin)在
engine {}块中使用DarwinClientEngineConfig配置引擎。例如,您可以使用configureRequest自定义请求或使用configureSession自定义会话:kotlinval client = HttpClient(Darwin) { engine { configureRequest { setAllowsCellularAccess(true) } } }完整示例请参阅 client-engine-darwin。
WinHttp
WinHttp 引擎针对基于 Windows 的操作系统。要使用 WinHttp 引擎,请按以下步骤操作:
添加
ktor-client-winhttp依赖项:KotlinGroovyXML将
WinHttp类作为参数传递给HttpClient构造函数:kotlinimport io.ktor.client.* import io.ktor.client.engine.winhttp.* val client = HttpClient(WinHttp)在
engine {}块中使用WinHttpClientEngineConfig配置引擎。例如,您可以使用protocolVersion属性更改 HTTP 版本:kotlinval client = HttpClient(WinHttp) { engine { protocolVersion = HttpProtocolVersion.HTTP_1_1 } }完整示例请参阅 client-engine-winhttp。
Curl
对于桌面平台,Ktor 提供了 Curl 引擎。它在 linuxX64、linuxArm64、macosX64、macosArm64 和 mingwX64 上受支持。要使用 Curl 引擎,请按以下步骤操作:
添加
ktor-client-curl依赖项:KotlinGroovyXML将
Curl类作为参数传递给HttpClient构造函数:kotlinimport io.ktor.client.* import io.ktor.client.engine.curl.* val client = HttpClient(Curl)在
engine {}块中使用CurlClientEngineConfig配置引擎。例如,出于测试目的禁用 SSL 验证:kotlinval 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。要使用它,请按以下步骤操作:
添加
ktor-client-cio依赖项:KotlinGroovyXML将
CIO类作为参数传递给HttpClient构造函数:kotlinimport io.ktor.client.* import io.ktor.client.engine.cio.* val client = HttpClient(CIO)在
engine {}块中使用CIOEngineConfig配置引擎:kotlinimport 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。要使用它,请按以下步骤操作:
添加
ktor-client-js依赖项:KotlinGroovyXML将
Js类作为参数传递给HttpClient构造函数:kotlinimport io.ktor.client.* import io.ktor.client.engine.js.* val client = HttpClient(Js)您也可以调用
JsClient()函数来获取Js引擎单例:kotlinimport io.ktor.client.engine.js.* val client = JsClient()
完整示例请参阅 client-engine-js。
限制
HTTP/2 和 WebSockets
并非所有引擎都支持 HTTP/2 协议。如果某个引擎支持 HTTP/2,您可以在该引擎的配置中启用它。例如,使用 Java 引擎。
下表显示了特定引擎是否支持 HTTP/2 和 WebSockets:
| 引擎 | HTTP/2 | WebSockets |
|---|---|---|
Apache5 | ✅️ | ✖️ |
Java | ✅ | ✅️ |
Jetty | ✅ | ✖️ |
CIO | ✖️ | ✅ |
Android | ✖️ | ✖️ |
OkHttp | ✅ | ✅ |
Js | ✅ | ✅ |
Darwin | ✅ | ✅ |
WinHttp | ✅ | ✅ |
Curl | ✅ | ✅ |
安全性
SSL 必须针对每个引擎进行配置。每个引擎都提供自己的 SSL 配置选项。
代理支持
某些引擎不支持代理。完整列表请参阅代理文档。
日志记录
Logging 插件根据目标平台提供不同的记录器类型。
超时
HttpTimeout 插件在某些引擎上有一些限制。完整列表请参阅超时限制。
示例:如何在多平台移动项目中配置引擎
在构建多平台项目时,您可以使用 expect 和 actual 声明为每个目标平台选择并配置引擎。这允许您在公共代码中共享大部分客户端配置,同时在平台代码中应用引擎特定的选项。 我们将使用在创建跨平台移动应用程序教程中创建的项目来演示如何实现这一点:
打开 shared/src/commonMain/kotlin/com/example/kmpktor/Platform.kt 文件,添加一个顶层的
httpClient()函数,该函数接受一个配置块并返回一个HttpClient:kotlinexpect fun httpClient(config: HttpClientConfig<*>.() -> Unit = {}): HttpClient打开 shared/src/androidMain/kotlin/com/example/kmpktor/Platform.kt,为 Android 模块添加
httpClient()函数的 actual 声明:kotlinimport 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 的引擎。打开 shared/src/iosMain/kotlin/com/example/kmpktor/Platform.kt,为 iOS 模块添加
httpClient()函数的 actual 声明:kotlinimport io.ktor.client.* import io.ktor.client.engine.darwin.* actual fun httpClient(config: HttpClientConfig<*>.() -> Unit) = HttpClient(Darwin) { config(this) engine { configureRequest { setAllowsCellularAccess(true) } } }现在您可以在公共代码中调用
httpClient(),而无需担心使用了哪个引擎。要在公共代码中使用该客户端,请打开 shared/src/commonMain/kotlin/com/example/kmpktor/Greeting.kt,并将
HttpClient()构造函数替换为httpClient()函数调用:kotlinprivate val client = httpClient()
