目前,我们正在将c制造的API网关引擎转换为tokio,hyper,rustls of rust.

在分析hyper_rustls(tokio_rustls)提供的echo服务器示例时,有一部分我不理解并请求帮助.

https://github.com/rustls/hyper-rustls/blob/main/examples/server.rs

以下是我想到的流程:

然而,一旦收到请求,就会执行传递给make_service_fn的代码,并向客户机发送响应,并且会多次执行tokio::io::AsyncRead特性的poll_read函数.这已经运行了.

问:make_fn_服务代码具体什么时候运行,这是我可以控制的吗?

Q: When using hyper, it seems to store the body accumulating in memory. Therefore, if the body size is very large, I would like to work with such as downloading it to a separate file. Is there a way to directly control every time the body comes?

  • 我可以使用hyper::body::HttpBody特性吗?

推荐答案

关于第一季度:

let service = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(echo)) });

调用make_fn_service将异步函数转换为可以传递给serve()的函数.它有一个&AddrStream类型的参数,可以做各种各样的事情,比如过滤和节流,但是如果你不需要这些,就用你的异步函数调用service_fn.

然后,您的函数(本例中为echo)将在每个客户端请求中调用一次.

关于第二季度:

身体不会积累在记忆中:

*response.body_mut() = req.into_body();

但它们是类型Body,实现Stream<Item=Result<Bytes>>,这Bytes是主体请求/响应的块.

通过将一个Stream切换到另一个Stream,一个非常大的ping应该可以毫无痛苦地通过echo函数,一次一个块.

如果你想自己管理数据,你可以轮询流(StreamExt::next())并单独处理身体的每一部分.不要打Body::to_bytes()Body::aggregate().

关于使用HttpBodytrait :

当然,你可以直接使用它,但它并不琐碎.我认为它通常是这样实现的,例如,您可以直接从请求中获取JSON对象,或者XML或urlencoded映射,或者您的内容类型所要求的任何内容,而无需执行中间字节数组和解析.

但正如您可能猜到的,在异步模式下处理巨大的XML/JSON有效负载并不容易.如果你真的需要的话,你可以让它更容易,只需要驱动普通Body的字节块.

Rust相关问答推荐

PyReadonlyArray2到Vec T<>

可以为rust构建脚本编写单元测试吗?

如何在Rust中基于字符串 Select struct ?

如何设置activx websocket actorless的消息大小限制?

Rust proc_macro 和 syn:解析空格

如何将 struct 数组放置在另一个 struct 的末尾而不进行内存分段

Rust 中的静态引用

Rust LinkedList 中的borrow 判断器错误的原因是什么?

更新 rust ndarray 中矩阵的一行

如何在 Rust 中显式声明 std::str::Matches<'a, P> ?

使用 lalrpop 在 rust 中解析由 " 引用的字符串

如何在 Rust 中将 Vec> 转换为 Vec>?

如何递归传递闭包作为参数?

Some(v) 和 Some(&v) 有什么区别?

哪些特征通过 `Deref` 而哪些不通过?

如何连接 Rust 中的相邻切片

切片不能被 `usize` 索引?

强制特征仅在 Rust 中的给定类型大小上实现

在 Rust 中为泛型 struct 编写一次特征绑定

在 Traits 函数中设置生命周期的问题