如何使用超体通道?

How to use Hyper body channel?

我正在尝试使用 Hyper 库发出 POST HTTP 请求,然后向其中写入数据直到关闭它(来自多个 functions/threads)。我在文档中发现我可以使用 Body::channel() 来执行此操作,但我使用不当,因为我只能向频道写入一次。我还没有找到任何例子,有人能给我指出正确的方向吗?

let (mut sender, body) = Body::channel();

let request = Request::builder()
    .method(Method::POST)
    .uri("http://localhost:3000/")
    .header("content-type", "text")
    .body(body)
    .unwrap();

let client = Client::new();
let response = client.request(request);

//Does get sent
println!("Body: {:?}", sender.send_data(hyper::body::Bytes::from("test\n")).await);
//Stuck on this one
println!("Body: {:?}", sender.send_data(hyper::body::Bytes::from("test2\n")).await);
//Debug print
println!("{:?}", response.await);

您需要将 send_data() 行换行到 tokio::spawn(async move { ... });.

问题是 Body/Sender 的缓冲区大小只有 1。所以第二个 send_data() 调用导致它 await(内部)直到 Sender准备好。这就是随后导致它“卡住”的原因。

这已通过使用 tokio::spawn() as it finally allows awaiting the ResponseFuture 解决,这会导致执行请求。

let (sender, body) = Body::channel();

let request = Request::builder()
    .method(Method::POST)
    .uri("http://localhost:3000/")
    .header("content-type", "text")
    .body(body)
    .unwrap();

let client = Client::new();

let response = client.request(request);

tokio::spawn(async move {
    let mut sender = sender;

    println!("Body: {:?}", sender.send_data(hyper::body::Bytes::from("test\n")).await);
    println!("Body: {:?}", sender.send_data(hyper::body::Bytes::from("test2\n")).await);
});

println!("{:?}", response.await);

文档中没有提到缓冲区大小(据我所知)。但是,您可以通过检查 source related to Body::channel(), where you can see it constructs a MPSC using futures_channel::mpsc::channel(0) 来弄清楚这一点。文档提到缓冲区大小为 buffer + num-senders,在我们的例子中为 0 + 1.