1 use hello_world::greeter_client::GreeterClient; 2 use hello_world::HelloRequest; 3 use service::AuthSvc; 4 5 use tonic::transport::Channel; 6 7 pub mod hello_world { 8 tonic::include_proto!("helloworld"); 9 } 10 11 #[tokio::main] 12 async fn main() -> Result<(), Box<dyn std::error::Error>> { 13 let channel = Channel::from_static("http://[::1]:50051").connect().await?; 14 let auth = AuthSvc::new(channel); 15 16 let mut client = GreeterClient::new(auth); 17 18 let request = tonic::Request::new(HelloRequest { 19 name: "Tonic".into(), 20 }); 21 22 let response = client.say_hello(request).await?; 23 24 println!("RESPONSE={:?}", response); 25 26 Ok(()) 27 } 28 29 mod service { 30 use http::{Request, Response}; 31 use std::future::Future; 32 use std::pin::Pin; 33 use std::task::{Context, Poll}; 34 use tonic::body::BoxBody; 35 use tonic::transport::Body; 36 use tonic::transport::Channel; 37 use tower::Service; 38 39 pub struct AuthSvc { 40 inner: Channel, 41 } 42 43 impl AuthSvc { 44 pub fn new(inner: Channel) -> Self { 45 AuthSvc { inner } 46 } 47 } 48 49 impl Service<Request<BoxBody>> for AuthSvc { 50 type Response = Response<Body>; 51 type Error = Box<dyn std::error::Error + Send + Sync>; 52 type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>; 53 54 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 55 self.inner.poll_ready(cx).map_err(Into::into) 56 } 57 58 fn call(&mut self, req: Request<BoxBody>) -> Self::Future { 59 let mut channel = self.inner.clone(); 60 61 Box::pin(async move { 62 // Do extra async work here... 63 64 channel.call(req).await.map_err(Into::into) 65 }) 66 } 67 } 68 } 69