tonic-h3 0.0.6

gRPC over HTTP/3 for Rust
Documentation

tonic-h3

build License: MIT Crates.io Documentation codecov

Experimental implementation of running tonic grpc on h3, following the proposal: G2-http3-protocol

tonic-h3 is targeted to support all quic transport implementations that integrates with h3.

Feature Backend Support
quinn Quinn (h3-quinn) production
msquic MsQuic (msquic-h3) experimental
s2n-quic s2n-quic (s2n-quic-h3) experimental
quiche quiche (quiche-h3) experimental

Note: Only the quinn backend is supported for production use. The msquic, s2n-quic, and quiche backends are experimental and provided for evaluation only.

See examples and tests for getting started.

Compatibility with grpc-dotnet with http3 is tested here.

Supporting crates

  • axum-h3 Use axum with h3, used by tonic-h3 server.
  • h3-util Http3 server and client utilities used by axum-h3 and tonic-h3.
  • Other quic wrapping crates to support alternative quic implementations.

Get started

Add deps to your cargo.toml

tonic-h3 = { version="*" , default-features = false, features = ["quinn"] }

tonic examples

Server:

  async fn run_server(endpoint: h3_quinn::quinn::Endpoint) -> Result<(), tonic_h3::Error> {
      let router = tonic::service::Routes::builder()
          .add_service(GreeterServer::new(HelloWorldService {}))
          .clone()
          .routes();
      let acceptor = tonic_h3::quinn::H3QuinnAcceptor::new(endpoint.clone());
      tonic_h3::server::H3Router::new(router)
          .serve(acceptor)
          .await?;
      endpoint.wait_idle().await;
      Ok(())
  }

Client:

  async fn run_client(
      uri: http::Uri,
      client_endpoint: h3_quinn::quinn::Endpoint,
  ) -> Result<(), tonic_h3::Error> {
      let connector = tonic_h3::quinn::H3QuinnConnector::new(
          uri.clone(),
          "localhost".to_string(),
          client_endpoint.clone(),
      );
      let channel = tonic_h3::H3Channel::new(connector, uri.clone(), None);
      let mut client = crate::greeter_client::GreeterClient::new(channel);
      let request = tonic::Request::new(crate::HelloRequest {
          name: "Tonic".into(),
      });
      let response = client.say_hello(request).await?;
      println!("RESPONSE={:?}", response);
      Ok(())
  }

License

MIT license. See LICENSE.