2025年webflux mono详解(webflux map)

webflux mono详解(webflux map)nbsp nbsp 今日科技快讯 nbsp nbsp 11 月 4 日 01 时 24 分 神舟十八号载人飞船返回舱在东风着陆场成功着陆 现场医监医保人员确认航天员叶光富 李聪 李广苏身体状态良好 神舟十八号载人飞行任务取得圆满成功 至此 80 后 乘组太空之旅圆满结束 航天员叶光富重返 天宫 的圆梦征程完美收官 刷新中国航天员在轨驻留时间的纪录

大家好,我是讯享网,很高兴认识大家。




讯享网

/   今日科技快讯   /

11月4日01时24分,神舟十八号载人飞船返回舱在东风着陆场成功着陆,现场医监医保人员确认航天员叶光富、李聪、李广苏身体状态良好,神舟十八号载人飞行任务取得圆满成功。

至此,“80后”乘组太空之旅圆满结束,航天员叶光富重返“天宫”的圆梦征程完美收官,刷新中国航天员在轨驻留时间的纪录,成为我国首位累计飞行时长超过一年的航天员。航天员李聪、李广苏的首飞之旅圆满完成。

/   作者简介   /

本篇文章转自bytebeats的博客,文章主要分享了Ktor 3.0中的变更以及迁移指南,相信会对大家有所帮助!

原文地址:
https://juejin.cn/post/

/   引言   /

Ktor 3.0 现已发布, 新增多项新特性并提高了性能

新版本 Ktor 基于 Kotlin 2.0 构建, 并切换到 kotlinx-io(https://github.com/Kotlin/kotlinx-io/), 使 Ktor 与时俱进, 并更好地与其他 Kotlin 工具连接. Ktor 3.0 运行速度更快, 为你提供了更多构建客户端-服务器应用的选项.

今天这篇文章我将将为你详细介绍 Ktor 3.0 的新特性和重要的性能改进.

/   正文   /

迁移到 kotlinx-io

新版本中最大的变化是切换到了基于 Okiohttps://github.com/square/okio) 的 kotlinx-io 库. 如果你使用 Ktor 的底层 IO API, 这一变更可能会对你产生影响. 正如基准测试所示, 这一改动是为了规范 Kotlin 库中的 IO 功能并提高性能.

  • 破坏性更改

这些更改主要影响底层 IO API, 包括 Input, Output, ByteReadChannel 和 ByteWriteChannel 等类. 如果直接使用这些类, 你将看到弃用警告. 你应该更新代码, 使用 kotlinx-io 库提供的替代类. 别担心, 在 4.0 版之前, 旧的 API会继续得到支持, 让你有充足的时间进行迁移.

新的 kotlinx-io 库提供了多平台 API, 可以处理各种数据源并提供一系列功能, 包括处理文件, 使用压缩等. 更多详情, 请查阅kotlinx-io API 文档https://kotlin.github.io/kotlinx-io/).

  • 性能改进

通过改用 kotlinx-io, 我们减少了 ByteReadChannel, ByteWriteChannel 和网络接口之间不必要的字节复制. 这使得字节转换和解析更加高效, 为未来的性能提升留出了空间.

我们的IO 基准https://github.com/ktorio/ktor-benchmarks/tree/main/io-benchmarks)测试基于真实的 Ktor 应用, 结果令人印象深刻. 一些测试结果表明, 性能提高了 90%以上, 我们还在努力进行更多改进.


支持服务器发送事件(SSE)

在 Ktor 3.0 中, 我们为服务器和客户端添加了对服务器发送事件(SSE)的初步支持.

服务器发送事件是一种能让服务器通过 HTTP 连接向客户端推送事件的技术. SSE 提供了从服务器到客户端的单向通信通道. 这种方法适用于服务器需要发送基于事件的更新而不需要客户端反复轮询新信息的情况.

要在 Ktor 应用中实现 SSE 支持, 首先要在项目的构建脚本中添加 SSE 依赖项:

implementation(“io.ktor:ktor-server-sse-jvm”

讯享网

接下来, 在 Ktor 应用中安装 SSE 插件, 并使用 sse{} 函数创建一个端点:

讯享网import io.ktor.server.application.
import io.ktor.server.engine.

import io.ktor.server.netty.
import io.ktor.server.routing.

import io.ktor.server.sse.
import io.ktor.sse.

import kotlinx.coroutines.delay

fun main() {
    embeddedServer(Netty, port = 8080) {
        install(SSE)
        routing {
            sse {
                repeat(42) {
                    val name = call.parameters[“name”] ?: “World”
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send(ServerSentEvent(data&nbsp;=&nbsp;“Hello,&nbsp;\(name</span>!&nbsp;<span style="color: #d19a66;line-height: 26px;">\)it))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delay(1000)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}.start(wait&nbsp;=&nbsp;true)
}

在sse{…}块中, 你可以访问一个具有以下功能的ServerSSESession实例.

  • send(): 创建并向客户端发送一个 ServerSentEvent.
  • call: 访问启动会话的关联ApplicationCall.
  • close(): 结束会话并终止连接: 结束会话并终止与客户端的连接.

请注意, Ktor 目前不支持 SSE 响应的数据压缩. 如果使用压缩插件, 默认情况下会跳过对 SSE 响应的压缩.

要使用 Ktor 客户端消费事件, 在最简单的情况下, 你只需在客户端实例上调用 sse 函数, 如下所示:

import&nbsp;io.ktor.client.
import&nbsp;io.ktor.client.engine.cio.

import&nbsp;io.ktor.client.plugins.sse.*
import&nbsp;kotlinx.coroutines.runBlocking

fun&nbsp;main()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;client&nbsp;=&nbsp;HttpClient(CIO)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;install(SSE)
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;runBlocking&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;client.sse(host&nbsp;=&nbsp;“127.0.0.1”,&nbsp;port&nbsp;=&nbsp;8080,&nbsp;path&nbsp;=&nbsp;”/sse”)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;incoming.collect&nbsp;{&nbsp;event&nbsp;-&gt;&nbsp;println(event)&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}

在上面的示例中, 只要服务器发送数据, 客户端就会消费事件.

从 ZIP 压缩包中提供静态资源

新函数 staticZip 允许用户将 ZIP 压缩包的内容作为静态内容提供.下面是一个如何使用它的基本示例:

讯享网routing&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;staticZip(
&nbsp;&nbsp;&nbsp;&nbsp;remotePath&nbsp;=&nbsp;”/”,
&nbsp;&nbsp;&nbsp;&nbsp;basePath&nbsp;=&nbsp;“base”,
&nbsp;&nbsp;&nbsp;&nbsp;Path(“files/text-files.zip”)
&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default(“file.txt”)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//modify&nbsp;the&nbsp;response&nbsp;by&nbsp;adding&nbsp;the&nbsp;HTTP&nbsp;Etag&nbsp;header
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;modify&nbsp;{&nbsp;path,&nbsp;call&nbsp;-&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call.response.headers.append(HttpHeaders.ETag,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path.fileName.toString())
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}

让我们将示例分解为几个关键部分:

  1. remotePath - 访问 ZIP 内容的基本 URL 路径.
  2. basePath - 希望提供的 ZIP 文件中的基本路径. 在我们的示例中, 我们假设 ZIP 压缩包包含base目录. 指定的basePath内的所有路径都将通过”remotePath/path/to/resource”递归访问. 这意味着你可以用子文件夹来组织你的 ZIP 文件, 它们将反映在 URL 结构中.
  3. Path(“files/text-files.zip”)- 你要提供的 ZIP 文件的路径.
  4. default() 函数 - 如果没有请求特定文件, 可使用该函数指定一个默认文件.
  5. modify块 - 这使你可以自定义响应. 在本例中, 我们根据文件名添加了一个 ETag 标头.

想要查看完整示例的话, 你可以参考 GitHub 上的 Ktor 示例代码库(https://github.com/ktorio/ktor-documentation/tree/3.0.0-beta-2/codeSnippets/snippets/static-zip).

支持 CSRF

新插件增加了对 CSRF(跨站请求伪造)https://owasp.org/www-community/attacks/csrf)保护的支持. 对 POST, PUT 和 DELETE 等改变状态的操作启用了保护.

一般来说, 它只适用于使用会话 cookie 和表单的项目, 因为启用该功能会使应用不必要地复杂化.

要在 Ktor 应用中启用 CSRF 支持, 首先要在项目的构建脚本中添加以下依赖项:

implementation(“io.ktor:ktor-server-csrf-jvm”

接下来, 你可以为应用中选定的路由启用 CSRF 保护, 如下所示:

讯享网route(”/csrf”)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;install(CSRF)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;allowOrigin(https://localhost:8080”)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;originMatchesHost()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;checkHeader(“X-CSRF”)&nbsp;{&nbsp;csrfHeader&nbsp;-&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request.headers[HttpHeaders.Origin]?.let&nbsp;{&nbsp;origin&nbsp;-&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;csrfHeader&nbsp;==&nbsp;origin.hashCode().toString(32)&nbsp;//&nbsp;1ndrgg9
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;==&nbsp;true
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onFailure&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;respondText(“Access&nbsp;denied!”,&nbsp;status&nbsp;=&nbsp;HttpStatusCode.Forbidden)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;post&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call.respondText(“CSRF&nbsp;check&nbsp;was&nbsp;successful”)
&nbsp;&nbsp;&nbsp;&nbsp;}
}

在配置块中, 插件提供了几种验证请求的方法:

  • allowOrigin 指定只允许来自预定义来源的请求. 在我们的例子中, 是 https://localhost:8080.
  • originMatchesHost 规定请求的来源必须与应用的主机相匹配.
  • checkHeader 支持任意头验证.

如果使用上述代码运行应用, 并使用 curl 命令向 /csrf 端点发送一个 POST 请求, 你将看到以下内容:

curl&nbsp;-X&nbsp;POST&nbsp;-H&nbsp;“Content-Type:&nbsp;application/json”&nbsp;–data&nbsp;’{}’&nbsp;http://localhost:8080/csrf

访问被拒绝了!添加所需的Header信息将使其通过检查::

讯享网curl&nbsp;-X&nbsp;POST&nbsp;-H&nbsp;“X-CSRF:&nbsp;1ndrgg9”&nbsp;-H&nbsp;“Origin:&nbsp;http://localhost:8080”&nbsp;-H&nbsp;“Content-Type:&nbsp;application/json”&nbsp;–data&nbsp;’{}’&nbsp;http://localhost:8080/csrf

CSRF 检查通过了!

Ktor 客户端支持 Wasm

Ktor 客户端现在支持将 WebAssembly(Wasm)作为构建目标. 虽然 Kotlin/Wasmhttps://kotlinlang.org/docs/wasm-overview.html) 仍处于早期阶段(Alpha), 但为 Ktor 客户端添加 Wasm 支持是扩展 Kotlin 多平台生态系统的重要一步. 为了展示这一新功能, 我们创建了一个示例 Compose Multiplatform 项目https://github.com/antonarhipov/ktor-samples-fork/tree/main/ktor-client-wasm), 该项目使用带有 WebAssembly (wasmJs) 目标的 Ktor 客户端.

要使用 Ktor 客户端, 你需要在项目的构建脚本中添加相应的依赖关系:

implementation(“io.ktor:ktor-client-core:$ktor_version)

迁移指南

Ktor 3.0 带来了一些重大变化. 官方为你准备了一份 迁移指南, 让你更轻松地过渡. 在此, 我们将重点介绍最显著的变化.

无论你是否将现有项目升级到 Ktor 3.0, 你都可以立即开始使用 Ktor 3.0 构建新项目!

  • 在TestApplication中明确加载模块

从现在起, TestApplicationhttps://api.ktor.io/ktor-server/ktor-server-test-host/io.ktor.server.testing/-test-application/index.html) 类要求显式加载模块. 下面的测试将启动一个空应用, 不会加载任何模块:

讯享网@Test
fun&nbsp;testRoot()&nbsp;=&nbsp;testApplication&nbsp;{//&nbsp;TestApplication&nbsp;scope
&nbsp;&nbsp;&nbsp;&nbsp;client.get(”/”).apply&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(HttpStatusCode.OK,&nbsp;status)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(“Hello&nbsp;World!”,&nbsp;bodyAsText())
&nbsp;&nbsp;&nbsp;&nbsp;}
}

相反的是, 你必须在 testApplicationhttps://api.ktor.io/ktor-server/ktor-server-test-host/io.ktor.server.testing/test-application.html)&nbsp;函数中明确加载模块, 或手动加载配置文件.

@Test
fun&nbsp;testRoot()&nbsp;=&nbsp;testApplication&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;application&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;configureRouting()
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;client.get(”/”).apply&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(HttpStatusCode.OK,&nbsp;status)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(“Hello&nbsp;World!”,&nbsp;bodyAsText())
&nbsp;&nbsp;&nbsp;&nbsp;}
}

  • 插件更新

CallLogging插件包已重命名, 修正了一个错别字:


注意: 请务必启用新的 Resources 插件替换 Locations 插件, 以实现类型安全路由.


这些变更旨在改进已有的 Ktor 的架构及其安全性和开发者体验. 从 Ktor 2.x 升级的用户请参考详细的 迁移指南https://ktor.io/docs/3.0.0-beta-2/migrating-3.html), 以确保顺利过渡到新版本.

今天的主要内容就是这些啦!

推荐阅读:
我的新书,《第一行代码 第3版》已出版!
Google 为何设计了如此难用的 ArrayMap
鸿蒙学习:大图缩放+轮播图+惯性滑动

欢迎关注我的公众号
学习技术或投稿

长按上图,识别图中二维码即可关注

小讯
上一篇 2025-04-20 23:06
下一篇 2025-06-08 19:53

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/185220.html