WebTransport

WebTransport 是一个基于 HTTP/3 的网络传输协议,提供了客户端和服务器之间的双向通信能力,同时兼顾了低延迟、高吞吐量和安全性。

应用场景

WebTransport 特别适合以下场景:

  • 实时应用:在线游戏、实时协作工具、视频会议等需要低延迟通信的应用
  • 大文件传输:支持高吞吐量的数据传输,适合媒体流和大文件上传下载
  • 多路复用通信:可以同时建立多个双向和单向数据流
  • 数据报文通信:支持不保证顺序和可靠性的数据报文通信,适合对实时性要求极高的场景

相比 WebSocket,WebTransport 提供了更低的延迟和更灵活的通信模式,特别是在不稳定的网络环境中表现更佳。

Salvo 实现

Salvo 框架提供了对 WebTransport 的内置支持,允许开发者轻松构建基于 WebTransport 的应用。主要特性包括:

  • 支持建立 WebTransport 会话
  • 支持双向流(Bidirectional Streams)通信
  • 支持单向流(Unidirectional Streams)通信
  • 支持数据报文(Datagrams)传输
  • 服务器可主动发起通信流

简单示例

下面是一个使用 Salvo 实现 WebTransport 服务器的简化示例:

#[handler]
async fn connect(req: &mut Request) -> Result<(), salvo::Error> {
    let session = req.web_transport_mut().await.unwrap();
    
    // 处理数据报文
    if let Ok(Some((_, datagram))) = session.accept_datagram().await {
        // 处理接收到的数据报文
        let mut resp = BytesMut::from(&b"Response: "[..]);
        resp.put(datagram);
        session.send_datagram(resp.freeze())?;
    }
    
    // 处理双向流
    if let Ok(Some(webtransport::server::AcceptedBi::BidiStream(_, stream))) = session.accept_bi().await {
        let (send, recv) = salvo::proto::quic::BidiStream::split(stream);
        // 处理双向流数据
    }
    
    Ok(())
}

配置与启动

启动一个支持 WebTransport 的 Salvo 应用需要配置 TLS 证书和 QUIC 监听器:

let cert = include_bytes!("../certs/cert.pem").to_vec();
let key = include_bytes!("../certs/key.pem").to_vec();

// 配置路由
let router = Router::new().push(Router::with_path("counter").goal(connect));

// 配置 TLS
let config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));

// 设置监听器
let listener = TcpListener::new(("0.0.0.0", 5800)).rustls(config.clone());
let acceptor = QuinnListener::new(config, ("0.0.0.0", 5800))
    .join(listener)
    .bind()
    .await;

// 启动服务器
Server::new(acceptor).serve(router).await;

完整示例

为了了解更多关于 Salvo 中 WebTransport 的使用方法,请查看 GitHub 上的完整示例: https://github.com/salvo-rs/salvo/blob/main/examples/webtransport

该示例包含了服务器端和客户端的完整实现,展示了如何处理各种类型的 WebTransport 通信。