From 9ea4a64a6cf719e6cdb90e9186eca6b9e4688521 Mon Sep 17 00:00:00 2001 From: Lucio Franco Date: Tue, 29 Sep 2020 11:16:07 -0400 Subject: [PATCH] examples: Add `tower-client` example (#466) --- examples/Cargo.toml | 6 +++- examples/src/tower/client.rs | 69 ++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 examples/src/tower/client.rs diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 483cf25..6edecbe 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -70,6 +70,10 @@ path = "src/tls_client_auth/client.rs" name = "tower-server" path = "src/tower/server.rs" +[[bin]] +name = "tower-client" +path = "src/tower/client.rs" + [[bin]] name = "multiplex-server" path = "src/multiplex/server.rs" @@ -163,4 +167,4 @@ tonic-health = { path = "../tonic-health" } listenfd = "0.3" [build-dependencies] -tonic-build = { path = "../tonic-build", features = ["prost"] } \ No newline at end of file +tonic-build = { path = "../tonic-build", features = ["prost"] } diff --git a/examples/src/tower/client.rs b/examples/src/tower/client.rs new file mode 100644 index 0000000..89da067 --- /dev/null +++ b/examples/src/tower/client.rs @@ -0,0 +1,69 @@ +use hello_world::greeter_client::GreeterClient; +use hello_world::HelloRequest; +use service::AuthSvc; + +use tonic::transport::Channel; + +pub mod hello_world { + tonic::include_proto!("helloworld"); +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + let channel = Channel::from_static("http://[::1]:50051").connect().await?; + let auth = AuthSvc::new(channel); + + let mut client = GreeterClient::new(auth); + + let request = tonic::Request::new(HelloRequest { + name: "Tonic".into(), + }); + + let response = client.say_hello(request).await?; + + println!("RESPONSE={:?}", response); + + Ok(()) +} + +mod service { + use http::{Request, Response}; + use std::future::Future; + use std::pin::Pin; + use std::task::{Context, Poll}; + use tonic::body::BoxBody; + use tonic::client::GrpcService; + use tonic::transport::Body; + use tonic::transport::Channel; + use tower::Service; + + pub struct AuthSvc { + inner: Channel, + } + + impl AuthSvc { + pub fn new(inner: Channel) -> Self { + AuthSvc { inner } + } + } + + impl Service> for AuthSvc { + type Response = Response; + type Error = Box; + type Future = Pin> + Send>>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx).map_err(Into::into) + } + + fn call(&mut self, req: Request) -> Self::Future { + let mut channel = self.inner.clone(); + + Box::pin(async move { + // Do extra async work here... + + channel.call(req).await.map_err(Into::into) + }) + } + } +}