Ktor 1.3 新版本现已发布!

Lei

Ktor 1.3 新版本最近发布!我们很高兴在此博客文章中与您分享详细信息。

Ktor 由两部分组成:服务器引擎和灵活性异步 HTTP 客户端。当前版本主要集中在 HTTP 客户端上。您可以在此处找到此版本的完整变更日志。

客户端是一个支持 JVM、JS、Android 和 iOS 的多平台库,现在经常在跨平台移动应用中使用。我们下一个版本的主要目标是使服务器引擎也可以跨平台运作。

我们将要研究的其他领域是:

  • 改进与 kotlinx.serialization 库的集成。

  • 在 Kotlin / Native 上支持 CIO (基于协同程序的 I / O 客户端引擎),使其成为 HttpClient 中使用的默认多平台引擎。

如果您当前使用的是服务器或 HttpClient 的 Ktor ,或者之前曾尝试过,请参加以下调查:

参与调查

如果您能与我们分享您的经验,我们会非常感激!

现在,让我们深入了解 Ktor 1.3 版本的细节。

HttpClient

HttpStatement 简介

在以前的 Ktor 版本中,您需要明确关闭 HttpResponse 。但是,这通常会使用户感到困惑。我们发现在很多情况下,即使在简单的示例中,也有人忘记了关闭 HttpResponse ,并因此而导致内存泄漏。为了改善这种情况,我们在 Ktor 1.3 中引入了不兼容的更改: HttpResponse 不再实现 Closeable 接口。因此,1.3.0 Ktor 发行版与先前版本的 Ktor 1.2.X 向后不兼容

现在在默认情况下, HttpResponse 处于内存中, 无再需手动关闭它:

fun main(): Unit = runBlocking {
    val client = HttpClient()
    val url = "http://kotlinlang.org/"
    val response = client.get<HttpResponse>(url)
    val text = response.readText()
    println(text)
    // no longer need to 'close' the response
}

如果需要处理流式处理或较大的响应,请使用新的 HttpStatement 类。在您明确地调用 execute 方法之前, HttpStatement 不会执行任何网络请求:
val statement = client.request<HttpStatement>("$TEST_SERVER/content/stream")
// ...
statement.execute { response: HttpResponse ->
    // working with the response
}

例如,您可以按部分读取数据:
client.get<HttpStatement>(url).execute { response ->
    val channel = response.receive<ByteReadChannel>()
    while (!channel.isClosedForRead) {
        val packet = channel.readRemaining(size)
        println(packet.readText())
    }
}

配置代理

HttpClient 添加了对代理的实验性支持。如果需要在代理下发送请求,则可以在相应的参数中配置其地址:

HttpClient { 
    engine { 
        proxy = ProxyBuilder.http("http://proxy-host:3128")
    }
}

请注意,由于平台的限制,它仅支持 JVM 和 Native 目标(WatchOS 除外),而 JavaScript 不支持。可以在此处找到有关如何针对不同平台进行配置的更多详细信息。

 NSURLSession 用于 iOS 引擎

iOS 引擎现在提供了一种配置 NSURLSession 的方法:

HttpClient(Ios) {
    engine {
        configureSession {
            networkServiceType = NSURLNetworkServiceTypeBackground
        }
    }
}

NSURLSession 是与 iOS 上的 HTTP / HTTPS 协议进行交互的默认 API ,因此现在您可以使用它来调整所有与 iOS 相关的设置。

使用 JSON 的改进

到目前为止,HttpClient 和服务器均支持以下更改,目前处于试验状态。

JSON 中的简化集合序列化

在以前的 Ktor 版本中,您需要注册辅助类型以序列化集合。现在,此过程已得到简化: JsonFeature 无需附加配置即可处理集合类型。现在不推荐使用所有相关功能,例如 setMapper  setListMapper 寄存器

不再需要在 JsonFeature 中注册 List <User> 

install(JsonFeature)
// ...
val list = client.get<List<User>>("https://example/json/users")&nbsp;<br>

在服务器上使用 JSON 时也是如此,可以在接收内容时使用预期的泛型参数指定集合类型:

install(ContentNegotiation) {
    register(ContentType.Application.Json, SerializationConverter())
}

routing {
    post("/entity") {
        val receivedList = call.receive<List<MyEntity>>()
        // process the list
    }
}

 

kotlinx.serialization DSL

Ktor 现在支持使用 kotlinx.serialization DSL 构造 JSON 正文的方法:

client.post<String>("http://localhost:9090") {
    contentType(ContentType.Application.Json)
    body = json {
        "key1" to 123
        "map" to json {
            "key2" to "abc"
        }
    }
}

要在客户端上使用它,请安装 JsonFeature 并添加 ktor-client-serialization 依赖项。在服务器上,使用 SerializationConverter 

 

迁移步骤

要将 Ktor 应用程序迁移到新版本,您需要:

  • 更新您对 HttpResponse 的所有用法:只需删除 close 调用,并在需要时使用 HttpStatement 

  • 更新导入。

    kotlinx.io 依赖性已被删除,因此您需要通过以下方式替换导入:

    • import kotlinx.io. -> import io.ktor.utils.io.

    • import kotlinx.coroutines.io. -> import io.ktor.utils.io.

请注意,它与 1.2.x 没有二进制兼容性,因此,如果您使用任何外部 Ktor 功能,则需要根据最新版本重新编译它们。

另外,请确保您使用的是 5.4.1+ Gradle 元数据版本。

感谢您阅读本文,请不要忘记参加调查!原文发表于2020年1月29日,作者Sergey Mashkov

参与调查