繁体   English   中英

如何使用 Rust 中新的 async-await 语法使用 H2 执行 HTTP2 请求?

[英]How to do an HTTP2 request with H2 using the new async-await syntax in Rust?

我遇到的问题是我尝试使用 Rust 的新 async-await 语法将H2 Akamai 示例转换为代码。

我已经能够生成以下代码,但它挂在let response = response.compat().await; 没有我能够理解为什么。

#![feature(async_await)]

use tokio::net::TcpStream;
use std::sync::Arc;
use webpki::DNSNameRef;
use futures::compat::Future01CompatExt;
use futures::future::{FutureExt, TryFutureExt};
use h2::client;
use rustls::ClientConfig;
use tokio_rustls::ClientConfigExt;

use rustls::Session;

use std::net::ToSocketAddrs;
use hyper::{Method, Request};

pub fn setup_config() -> Arc<ClientConfig>
{
    std::sync::Arc::new({
        let mut c = rustls::ClientConfig::new();
        c.root_store
            .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
        c.alpn_protocols.push("h2".to_owned());
        c
    })
}

pub async fn worker()
{
    // Set the address to run our socket on.
    let address = "http2.akamai.com:443"
        .to_socket_addrs()
        .unwrap()
        .next()
        .unwrap();

    let config = setup_config();

    let dns_name = DNSNameRef::try_from_ascii_str("http2.akamai.com").unwrap();

    // Open a TCP connection.
    let tcp = TcpStream::connect(&address).compat().await.unwrap();
    ;

    let tls = config.connect_async(dns_name, tcp).compat().await.unwrap();

    let (_, session) = tls.get_ref();
    let negotiated_protocol = session.get_alpn_protocol();
    assert_eq!(Some("h2"), negotiated_protocol.as_ref().map(|x| &**x));

    let res = client::handshake(tls).compat().await;

    let (client, h2) = res.unwrap();

    println!("Test5");
    let request = Request::builder()
        .method(Method::GET)
        .uri("https://http2.akamai.com/")
        .body(())
        .unwrap();

    println!("Test6");

    let (response, x) = client.ready().compat().await.unwrap().send_request(request, true).unwrap();
    println!("Test7");

    let response = response.compat().await;
    println!("Test8");
}

fn main()
{
    // Call our `run_server` function, which returns a future.
    // As with every `async fn`, for `run_server` to do anything,
    // the returned future needs to be run. Additionally,
    // we need to convert the returned future from a futures 0.3 future into a
    // futures 0.1 future.
    let futures_03_future = worker();
    let futures_01_future = futures_03_future.unit_error().boxed().compat();

    // Finally, we can run the future to completion using the `run` function
    // provided by Hyper.
    tokio::run(futures_01_future);
}

货物.toml:

[dependencies]
# The latest version of the "futures" library, which has lots of utilities
# for writing async code. Enable the "compat" feature to include the
# functions for using futures 0.3 and async/await with the Hyper library,
# which use futures 0.1.
futures-preview = { version = "=0.3.0-alpha.16", features = ["compat"] }

# Hyper is an asynchronous HTTP library. We'll use it to power our HTTP
# server and to make HTTP requests.
hyper = "0.12.9"

# Tokio
tokio = "0.1.22"
h2 = "0.1.26"

# RustTLS
rustls = "0.12"
tokio-rustls = "0.5.0"
webpki = "0.18"
webpki-roots = "0.14"

输出:

Test5
Test6
Test7

我希望您能够帮助我了解为什么它在此请求期间挂起。

编辑:我也检查了 Wireshark,并且 HTTP2 连接已打开,但未发送连接内的请求。 但我还是不明白为什么。

我也忘了在新线程上生成连接:

tokio::spawn(h2.map_err(|_| panic!("connection failed")));

有关更多信息,请参阅:

https://github.com/hyperium/h2/issues/390

https://github.com/hyperium/h2/issues/391

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM