xref: /tonic/examples/src/tower/server.rs (revision 61555ff2)
1 use hyper::{Body, Request as HyperRequest, Response as HyperResponse};
2 use std::task::{Context, Poll};
3 use tonic::{
4     body::BoxBody,
5     transport::{NamedService, Server},
6     Request, Response, Status,
7 };
8 use tower::Service;
9 
10 use hello_world::greeter_server::{Greeter, GreeterServer};
11 use hello_world::{HelloReply, HelloRequest};
12 
13 pub mod hello_world {
14     tonic::include_proto!("helloworld");
15 }
16 
17 #[derive(Default)]
18 pub struct MyGreeter {}
19 
20 #[tonic::async_trait]
21 impl Greeter for MyGreeter {
22     async fn say_hello(
23         &self,
24         request: Request<HelloRequest>,
25     ) -> Result<Response<HelloReply>, Status> {
26         println!("Got a request from {:?}", request.remote_addr());
27 
28         let reply = hello_world::HelloReply {
29             message: format!("Hello {}!", request.into_inner().name),
30         };
31         Ok(Response::new(reply))
32     }
33 }
34 
35 #[tokio::main]
36 async fn main() -> Result<(), Box<dyn std::error::Error>> {
37     let addr = "[::1]:50051".parse().unwrap();
38     let greeter = MyGreeter::default();
39 
40     println!("GreeterServer listening on {}", addr);
41 
42     let svc = InterceptedService {
43         inner: GreeterServer::new(greeter),
44     };
45 
46     Server::builder().add_service(svc).serve(addr).await?;
47 
48     Ok(())
49 }
50 
51 #[derive(Debug, Clone)]
52 struct InterceptedService<S> {
53     inner: S,
54 }
55 
56 impl<S> Service<HyperRequest<Body>> for InterceptedService<S>
57 where
58     S: Service<HyperRequest<Body>, Response = HyperResponse<BoxBody>>
59         + NamedService
60         + Clone
61         + Send
62         + 'static,
63     S::Future: Send + 'static,
64 {
65     type Response = S::Response;
66     type Error = S::Error;
67     type Future = futures::future::BoxFuture<'static, Result<Self::Response, Self::Error>>;
68 
69     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
70         self.inner.poll_ready(cx)
71     }
72 
73     fn call(&mut self, req: HyperRequest<Body>) -> Self::Future {
74         let mut svc = self.inner.clone();
75 
76         Box::pin(async move {
77             // Do async work here....
78 
79             svc.call(req).await
80         })
81     }
82 }
83 
84 impl<S: NamedService> NamedService for InterceptedService<S> {
85     const NAME: &'static str = S::NAME;
86 }
87