use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};
use std::convert::Infallible;
use std::net::SocketAddr;
// 处理请求的函数
async fn handle_request(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
let html_content = r#"
<html>
<head>
<title>自定义HTML</title>
</head>
<body>
<h1>这是一个自定义的HTML内容</h1>
</body>
</html>
"#;
let response = Response::new(Body::from(html_content));
Ok(response)
}
// 创建服务工厂
async fn make_service(_addr: SocketAddr) -> Result<impl hyper::service::Service<Request<Body>, Response = Response<Body>, Error = Infallible>, hyper::Error> {
Ok(make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle_request)) }))
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let server = Server::bind(&addr).serve(make_service);
println!("服务器在 http://{} 启动", addr);
if let Err(e) = server.await {
eprintln!("服务器错误: {}", e);
}
Ok(())
}
优化思路
- 并发处理:
hyper
库基于Tokio
,Tokio
是一个异步运行时,它允许我们轻松地处理并发请求。Server::serve
方法会自动为每个传入的请求生成一个新的任务(task
),这些任务可以并行处理,从而极大地提高服务器处理并发请求的能力。在代码中,make_service_fn
和service_fn
的使用,结合async
/await
语法,使得请求处理能够以异步方式并发执行。
- 减少内存开销:
- 复用缓冲区:在处理请求和响应时,
hyper
库会尽量复用缓冲区以减少内存分配。在上述代码中,虽然没有显式地控制缓冲区复用,但hyper
库底层已经做了这方面的优化。例如,Body::from(html_content)
将字符串内容转换为Body
时,hyper
会合理地管理相关的内存。
- 避免不必要的复制:在
handle_request
函数中,直接返回包含HTML内容的Response
,没有进行额外的不必要的数据复制操作,从而减少了内存开销。同时,使用字符串字面量来定义HTML内容,这些内容在编译时就确定,不会在运行时额外分配内存。