面试题答案
一键面试设计思路
- 客户端:
- 使用
hyper
库(它支持HTTP/2 且底层对多路复用和流量控制有较好的支持)来构建客户端。 - 初始化一个
Client
实例,通过这个实例发起HTTP请求。hyper
库会自动处理多路复用,在一个连接上可以并发发送多个请求。 - 对于流量控制,
hyper
底层基于HTTP/2协议的流量控制机制,会根据接收方的窗口大小自动调整数据发送速率。
- 使用
- 服务器:
- 同样使用
hyper
库来搭建HTTP/2服务器。 - 定义路由,处理不同的请求路径。
hyper
的Server
会自动处理多路复用,使得多个请求可以在同一个连接上并发处理。 - 流量控制方面,
hyper
库基于HTTP/2协议的标准流量控制,服务器在发送数据时会根据客户端反馈的窗口大小来调整发送速率。
- 同样使用
关键代码实现
- 客户端代码:
use hyper::client::HttpConnector;
use hyper::{Body, Client, Request, Uri};
use std::convert::Infallible;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let http = HttpConnector::new();
let client = Client::builder().build::<_, Body>(http);
let uri = Uri::try_from("https://example.com")?;
let request = Request::builder()
.uri(uri)
.header("content-type", "application/json")
.body(Body::from(""))?;
let response = client.request(request).await?;
println!("Response status: {}", response.status());
Ok(())
}
- 服务器代码:
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};
use std::convert::Infallible;
async fn handle_request(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
let response_body = "Hello, World!".to_string();
Ok(Response::new(Body::from(response_body)))
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let make_svc = make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(handle_request))
});
let server = Server::bind(&"0.0.0.0:3000".parse()?)
.serve(make_svc);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
Ok(())
}
在上述代码中,客户端通过hyper
库的Client
发送HTTP请求,服务器通过hyper
库的Server
接收并处理请求,hyper
库内部已经很好地实现了HTTP/2的多路复用和流量控制机制。