diff --git a/examples/Cargo.toml b/examples/Cargo.toml index bf49098..5a781b3 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -94,6 +94,14 @@ path = "src/interceptor/client.rs" name = "interceptor-server" path = "src/interceptor/server.rs" +[[bin]] +name = "hyper-client" +path = "src/hyper/client.rs" + +[[bin]] +name = "hyper-server" +path = "src/hyper/server.rs" + [dependencies] tonic = { path = "../tonic", features = ["tls"] } prost = "0.6" @@ -112,6 +120,8 @@ tracing-attributes = "0.1" tracing-futures = "0.2" # Required for wellknown types prost-types = "0.6" +# Hyper example +hyper = "0.13" [build-dependencies] tonic-build = { path = "../tonic-build" } diff --git a/examples/src/hyper/client.rs b/examples/src/hyper/client.rs new file mode 100644 index 0000000..bc17190 --- /dev/null +++ b/examples/src/hyper/client.rs @@ -0,0 +1,42 @@ +use hello_world::greeter_client::GreeterClient; +use hello_world::HelloRequest; +use hyper::{Client, Uri}; + +pub mod hello_world { + tonic::include_proto!("helloworld"); +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::builder().http2_only(true).build_http(); + + let uri = Uri::from_static("http://[::1]:50051"); + + // Hyper's client requires that requests contain full Uris include a scheme and + // an authority. Tonic's transport will handle this for you but when using the client + // manually you need ensure the uri's are set correctly. + let add_origin = tower::service_fn(|mut req: hyper::Request| { + let uri = Uri::builder() + .scheme(uri.scheme().unwrap().clone()) + .authority(uri.authority().unwrap().clone()) + .path_and_query(req.uri().path_and_query().unwrap().clone()) + .build() + .unwrap(); + + *req.uri_mut() = uri; + + client.request(req) + }); + + let mut client = GreeterClient::new(add_origin); + + let request = tonic::Request::new(HelloRequest { + name: "Tonic".into(), + }); + + let response = client.say_hello(request).await?; + + println!("RESPONSE={:?}", response); + + Ok(()) +} diff --git a/examples/src/hyper/server.rs b/examples/src/hyper/server.rs new file mode 100644 index 0000000..f2d725d --- /dev/null +++ b/examples/src/hyper/server.rs @@ -0,0 +1,46 @@ +use futures::future; +use hyper::{service::make_service_fn, Server}; +use std::convert::Infallible; +use tonic::{Request, Response, Status}; + +use hello_world::greeter_server::{Greeter, GreeterServer}; +use hello_world::{HelloReply, HelloRequest}; + +pub mod hello_world { + tonic::include_proto!("helloworld"); +} + +#[derive(Default)] +pub struct MyGreeter {} + +#[tonic::async_trait] +impl Greeter for MyGreeter { + async fn say_hello( + &self, + request: Request, + ) -> Result, Status> { + let reply = hello_world::HelloReply { + message: format!("Hello {}!", request.into_inner().name), + }; + Ok(Response::new(reply)) + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + let addr = "[::1]:50051".parse().unwrap(); + let greeter = MyGreeter::default(); + + println!("GreeterServer listening on {}", addr); + + let svc = GreeterServer::new(greeter); + + Server::bind(&addr) + .http2_only(true) + .serve(make_service_fn(|_| { + future::ok::<_, Infallible>(svc.clone()) + })) + .await?; + + Ok(()) +}