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 通訊。