客户端引擎
Ktor HTTP 客户端 是多平台的,可在 JVM、Android、JavaScript(包括 WebAssembly)以及 Native 目标平台运行。每个平台都需要一个特定的引擎来处理网络请求。例如,对于 JVM 应用程序,可以使用 Apache
或 Jetty
;对于 Android,可以使用 OkHttp
或 Android
;对于面向 Kotlin/Native 的桌面应用程序,可以使用 Curl
。每个引擎在特性和配置上略有不同,因此你可以选择最符合你的平台和用例需求的引擎。
支持的平台
下表列出了每个引擎支持的平台:
Engine | Platforms |
---|---|
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 版本:
Engine | Android version | Java version |
---|---|---|
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
artifact 之外,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 customizeClient { // this: HttpAsyncClientBuilder setProxy(HttpHost("127.0.0.1", 8080)) // ... } customizeRequest { // this: RequestConfig.Builder } } }
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 } }
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:
Engine | HTTP/2 | WebSockets |
---|---|---|
Apache5 | ✅️ | ✖️ |
Java | ✅ | ✅️ |
Jetty | ✅ | ✖️ |
CIO | ✖️ | ✅ |
Android | ✖️ | ✖️ |
OkHttp | ✅ | ✅ |
Js | ✅ | ✅ |
Darwin | ✅ | ✅ |
WinHttp | ✅ | ✅ |
Curl | ✅ | ✅ |
安全性
SSL 必须按引擎配置。每个引擎都提供自己的 SSL 配置选项。
代理支持
一些引擎不支持代理。有关完整列表,请参见代理文档。
日志记录
Logging 插件根据目标平台提供不同的日志记录器类型。
超时
HttpTimeout 插件对某些引擎有一些限制。有关完整列表,请参见超时限制。
示例:如何在多平台移动项目配置引擎
在构建多平台项目时,你可以使用期望与实际声明来为每个目标平台选择和配置引擎。这允许你在公共代码中共享大部分客户端配置,同时在平台代码中应用引擎特有的选项。我们将使用在创建跨平台移动应用程序教程中创建的项目来演示如何实现这一点:
打开 shared/src/commonMain/kotlin/com/example/kmmktor/Platform.kt 文件,并添加一个顶层
httpClient()
函数,该函数接受配置代码块并返回一个HttpClient
:kotlinexpect fun httpClient(config: HttpClientConfig<*>.() -> Unit = {}): HttpClient
打开 shared/src/androidMain/kotlin/com/example/kmmktor/Platform.kt,并为 Android 模块添加
httpClient()
函数的实际声明: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/kmmktor/Platform.kt,并为 iOS 模块添加
httpClient()
函数的实际声明: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/kmmktor/Greeting.kt,并将
HttpClient()
构造函数替换为httpClient()
函数调用:kotlinprivate val client = httpClient()