zerust 1.0.4

Zero-cost Zinx for Rust
Documentation
//! # 服务器核心模块
//!
//! 该模块提供了TCP服务器的核心功能,包括监听连接、处理请求和响应等。
//! 它是框架的主要入口点,负责协调各个组件的工作。
//!
//! ## 主要功能
//!
//! * 绑定并监听TCP端口
//! * 接收客户端连接
//! * 为每个连接创建独立的异步任务
//! * 协调路由器和连接管理器的工作

use crate::{connection::Connection, error::ZerustError, router::Router};
use std::sync::Arc;
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::oneshot;

/// 表示一个TCP服务器
///
/// `Server` 是框架的主要入口点,负责监听TCP连接并处理客户端请求。
/// 它使用 `Router` 来分发请求,使用 `Connection` 来管理客户端连接。
pub struct Server {
    /// 服务器监听的地址,格式为 "IP:端口"
    addr: String,
    /// 路由器实例,用于分发请求到对应的处理函数
    ///
    /// 使用 `Arc` 包装,可以在多个线程间安全地共享数据
    router: Arc<dyn Router + Send + Sync>,
}

impl Server {
    /// 创建一个新的服务器实例
    ///
    /// # 参数
    /// * `addr` - 服务器监听的地址,格式为 "IP:端口"
    /// * `router` - 路由器实例,用于分发请求到对应的处理函数
    ///
    /// # 返回值
    /// 返回一个新的 `Server` 实例
    pub fn new(addr: &str, router: Arc<dyn Router + Send + Sync>) -> Self {
        Self {
            addr: addr.to_string(),
            router,
        }
    }

    /// 启动服务器并监听指定地址的TCP连接
    ///
    /// 该函数会绑定到配置的地址并开始监听TCP连接,对于每个传入的连接,
    /// 都会创建一个异步任务来处理请求。如果在监听过程中发生IO错误,
    /// 函数会立即返回错误。
    ///
    /// # 参数
    ///
    /// * `shutdown`: 接收关闭信号的通道。当发送端被 drop 或发送消息时,服务器将关闭。
    ///
    /// # 返回值
    ///
    /// * `Ok(())` - 服务器正常启动并运行
    /// * `Err(ZerustError)` - 服务器启动或运行过程中发生错误
    pub async fn run(&self, mut shutdown: oneshot::Receiver<()>) -> Result<(), ZerustError> {
        // 绑定TCP监听器到指定地址
        let listener = TcpListener::bind(&self.addr).await?;

        // 持续接受并处理客户端连接
        loop {
            // 使用tokio::select! 同时监听:
            // 1. 新的客户端连接
            // 2. 关闭信息
            tokio::select! {
                // 分支1 :接收新连接
                accept_result = listener.accept() =>{
                    match accept_result {
                        Ok((stream, _addr)) => {
                            // 为每个连接创建独立的异步任务进行处理
                            let router = self.router.clone();
                            tokio::spawn(async move {
                                let _ = Self::handle_connection(stream, router).await;
                            });
                        }
                        Err(e) => return Err(ZerustError::IoError(e)),
                     }
                }
                // 分支2 : 接受关闭信号
                _ = &mut shutdown =>{
                    break Ok(()) // 退出 loop,结束 run
                }
            }
        }
    }

    /// 处理TCP连接的异步函数
    ///
    /// 该函数负责接收并处理来自客户端的HTTP请求,通过路由器分发请求并返回响应
    ///
    /// # 参数
    /// * `stream` - TCP流连接,用于与客户端进行数据通信
    /// * `router` - 路由器实例,用于处理HTTP请求并生成响应
    ///
    /// # 返回值
    /// * `Result<(), ZerustError>` - 成功时返回空元组,失败时返回Zerust错误
    async fn handle_connection(
        stream: TcpStream,
        router: Arc<dyn Router>,
    ) -> Result<(), ZerustError> {
        let mut conn = Connection::new(stream);

        // 持续处理来自同一连接的多个请求
        loop {
            // 读取客户端发送的HTTP请求
            let req = match conn.read_request().await {
                Ok(req) => req,
                Err(e) => {
                    return Err(e);
                }
            };

            let resp = router.handle(&req);
            conn.send_response(&resp).await?;
        }
    }
}