hyper 是一个用 Rust 语言写的高性能、异步的 HTTP 库,支持 HTTP/1 和 HTTP/2 协议,既能做客户端,也能做服务器端。它是一个"底层"库,主要用来构建其他网络库或应用,适合需要高性能和灵活控制的场景。
hyper 的核心特点
- 高性能:设计时注重吞吐量和响应速度,适合高并发网络服务。
- 异步支持:基于 Rust 的异步编程(async/await),能高效处理大量并发请求。
- 支持多协议:支持 HTTP/1 和 HTTP/2,未来还会支持 HTTP/3。
- 底层灵活:提供对 HTTP 协议细节的完全控制,适合自定义连接和请求处理。
- 客户端和服务器:既能写 HTTP 客户端,也能搭建 HTTP 服务器。
- 安全可靠:利用 Rust 的内存安全特性,减少运行时错误,适合生产环境。
适合使用 hyper 的场景
- 需要构建高性能、可扩展的 HTTP 服务或客户端。
- 希望对 HTTP 协议细节有完全控制权。
- 想基于 Rust 异步生态(如 Tokio)开发网络应用。
- 作为更高级框架(如 axum、warp)的底层依赖。
- 构建微服务、代理服务、RESTful API 等高并发场景。
如果你只想快速写一个简单的 HTTP 客户端,可以用更高层的库如 reqwest;想快速搭建 Web 服务器,可以用基于 hyper 的框架如 axum 或 warp。
hyper 解决了什么问题?
- 高效异步处理 HTTP 请求和响应。
- 实现符合 HTTP 标准的客户端和服务器。
- 灵活管理连接和协议,满足复杂网络需求。
- 作为构建复杂网络服务的基础,支持自定义扩展。
- 满足 Rust 生态对安全、性能和协议正确性的需求。
最简单的 hyper HTTP 服务器示例
下面是一个用 hyper 写的最简单 HTTP 服务器,监听本地 3000 端口,访问时返回 "Hello, World!"。
rust
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};
use std::convert::Infallible;
use std::net::SocketAddr;
// 处理请求,返回固定响应
async fn hello_world(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
Ok(Response::new(Body::from("Hello, World!")))
}
#[tokio::main]
async fn main() {
// 监听地址和端口
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
// 创建服务工厂,每个连接都会调用
let make_svc = make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(hello_world))
});
// 创建并启动服务器
let server = Server::bind(&addr).serve(make_svc);
println!("服务器运行在 http://{}", addr);
// 运行服务器,等待请求
if let Err(e) = server.await {
eprintln!("服务器错误: {}", e);
}
}
运行步骤
- 新建 Rust 项目,编辑
Cargo.toml
添加依赖:
text
[dependencies]
hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1", features = ["full"] }
- 将上面代码保存为
main.rs
。 - 执行命令启动服务器:
arduino
bash
cargo run
- 打开浏览器访问
http://localhost:3000
,页面显示:
arduino
text
Hello, World!
进阶示例:带路由的简单服务器
下面示例展示如何根据请求路径返回不同内容:
rust
use hyper::{Body, Request, Response, Server, Method, StatusCode};
use hyper::service::{make_service_fn, service_fn};
use std::convert::Infallible;
use std::net::SocketAddr;
async fn router(req: Request<Body>) -> Result<Response<Body>, Infallible> {
match (req.method(), req.uri().path()) {
(&Method::GET, "/") => Ok(Response::new(Body::from("主页"))),
(&Method::GET, "/hello") => Ok(Response::new(Body::from("你好,世界!"))),
_ => {
let mut not_found = Response::new(Body::from("404 - 未找到"));
*not_found.status_mut() = StatusCode::NOT_FOUND;
Ok(not_found)
}
}
}
#[tokio::main]
async fn main() {
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let make_svc = make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(router))
});
let server = Server::bind(&addr).serve(make_svc);
println!("服务器运行在 http://{}", addr);
if let Err(e) = server.await {
eprintln!("服务器错误: {}", e);
}
}
访问 http://localhost:3000/
显示"主页",访问 http://localhost:3000/hello
显示"你好,世界!",其他路径返回 404。
hyper 客户端简单示例
hyper 也可以用来写 HTTP 客户端,下面示例演示如何发送 GET 请求并打印响应体:
rust
use hyper::{Client, Uri};
use hyper::body::to_bytes;
use tokio;
#[tokio::main]
async fn main() {
let client = Client::new();
let uri: Uri = "http://httpbin.org/get".parse().unwrap();
match client.get(uri).await {
Ok(res) => {
println!("响应状态: {}", res.status());
let body_bytes = to_bytes(res.into_body()).await.unwrap();
println!("响应体: {}", String::from_utf8_lossy(&body_bytes));
}
Err(err) => {
eprintln!("请求错误: {}", err);
}
}
}
总结
- hyper 是 Rust 生态中一个底层且高性能的 HTTP 库,支持异步和多协议。
- 适合需要灵活控制 HTTP 细节和高性能的网络应用。
- 既能做客户端,也能做服务器端。
- 结合 Tokio 异步运行时,能高效处理大量并发请求。
- 初学者可以从简单示例入手,逐步学习路由、请求处理、连接管理等高级功能。
- 适合构建微服务、代理、RESTful API 等高并发场景。
通过以上示例和说明,您可以快速理解 hyper 的基础知识,并动手写出自己的高性能 HTTP 应用。