Tencent / tquic

A high-performance, lightweight, and cross-platform QUIC library
https://tquic.net/
Other
1.02k stars 82 forks source link

怎样异步运行Server #290

Closed OstrichRunning closed 2 months ago

OstrichRunning commented 2 months ago

我看demo上运行一个Server就进入一个loop,如果我想同时启动v4和v6两个socket,我该怎样做? 当我使用tokio::spawn(async move {} 时 报下面的错误 (dyn Http3Handler + 'static) cannot be shared between threads safely

麻烦帮看看下,如何能异步启动服务

glime-ai[bot] commented 2 months ago

要同时启动IPv4和IPv6两个socket,并且异步启动服务,你可以参考以下步骤:

  1. 创建两个不同的SocketAddr,一个用于IPv4,一个用于IPv6。
  2. 使用tokio::spawn来启动两个不同的任务,每个任务监听一个socket。
  3. 确保你的Http3Handler实现了SendSync trait,以便它可以在多个线程之间安全地共享。

以下是一个简单的示例代码:

use tokio::net::TcpListener;
use tokio::runtime::Runtime;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let ipv4_addr = "127.0.0.1:8080".parse()?;
    let ipv6_addr = "[::1]:8080".parse()?;

    let listener_v4 = TcpListener::bind(ipv4_addr).await?;
    let listener_v6 = TcpListener::bind(ipv6_addr).await?;

    let handler = Arc::new(MyHttp3Handler::new());

    let handler_v4 = handler.clone();
    let handler_v6 = handler.clone();

    tokio::spawn(async move {
        loop {
            let (socket, _) = listener_v4.accept().await.unwrap();
            let handler = handler_v4.clone();
            tokio::spawn(async move {
                // 处理连接
                handler.handle(socket).await;
            });
        }
    });

    tokio::spawn(async move {
        loop {
            let (socket, _) = listener_v6.accept().await.unwrap();
            let handler = handler_v6.clone();
            tokio::spawn(async move {
                // 处理连接
                handler.handle(socket).await;
            });
        }
    });

    // 保持主线程运行
    loop {
        tokio::time::sleep(tokio::time::Duration::from_secs(60)).await;
    }
}

struct MyHttp3Handler;

impl MyHttp3Handler {
    fn new() -> Self {
        MyHttp3Handler
    }

    async fn handle(&self, socket: tokio::net::TcpStream) {
        // 处理连接的逻辑
    }
}

// 确保你的Handler实现了Send和Sync
unsafe impl Send for MyHttp3Handler {}
unsafe impl Sync for MyHttp3Handler {}

在这个示例中,我们创建了两个TcpListener,分别监听IPv4和IPv6地址。然后,我们使用tokio::spawn启动两个异步任务,每个任务处理一个监听器的连接。为了确保Http3Handler可以在多个线程之间共享,我们使用了Arc并确保它实现了SendSync

This comment was generated by Glime.

iyangsj commented 2 months ago

目前暂未提供异步Rust风格的接口,后续版本会支持