| use tonic::{transport::Server, 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<HelloRequest>, |
| ) -> Result<Response<HelloReply>, Status> { |
| let extension = request.extensions().get::<MyExtension>().unwrap(); |
| println!("extension data = {}", extension.some_piece_of_data); |
| |
| let reply = hello_world::HelloReply { |
| message: format!("Hello {}!", request.into_inner().name), |
| }; |
| Ok(Response::new(reply)) |
| } |
| } |
| |
| #[tokio::main] |
| async fn main() -> Result<(), Box<dyn std::error::Error>> { |
| let addr = "[::1]:50051".parse().unwrap(); |
| let greeter = MyGreeter::default(); |
| |
| // See examples/src/interceptor/client.rs for an example of how to create a |
| // named interceptor that can be returned from functions or stored in |
| // structs. |
| let svc = GreeterServer::with_interceptor(greeter, intercept); |
| |
| println!("GreeterServer listening on {}", addr); |
| |
| Server::builder().add_service(svc).serve(addr).await?; |
| |
| Ok(()) |
| } |
| |
| /// This function will get called on each inbound request, if a `Status` |
| /// is returned, it will cancel the request and return that status to the |
| /// client. |
| fn intercept(mut req: Request<()>) -> Result<Request<()>, Status> { |
| println!("Intercepting request: {:?}", req); |
| |
| // Set an extension that can be retrieved by `say_hello` |
| req.extensions_mut().insert(MyExtension { |
| some_piece_of_data: "foo".to_string(), |
| }); |
| |
| Ok(req) |
| } |
| |
| struct MyExtension { |
| some_piece_of_data: String, |
| } |