| use tonic::{transport::Server, Request, Response, Status}; |
| |
| use hello_world::greeter_server::{Greeter, GreeterServer}; |
| use hello_world::{HelloReply, HelloRequest}; |
| use std::time::Duration; |
| use tonic_health::server::HealthReporter; |
| |
| 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> { |
| println!("Got a request from {:?}", request.remote_addr()); |
| |
| let reply = hello_world::HelloReply { |
| message: format!("Hello {}!", request.into_inner().name), |
| }; |
| Ok(Response::new(reply)) |
| } |
| } |
| |
| /// This function (somewhat improbably) flips the status of a service every second, in order |
| /// that the effect of `tonic_health::HealthReporter::watch` can be easily observed. |
| async fn twiddle_service_status(mut reporter: HealthReporter) { |
| let mut iter = 0u64; |
| loop { |
| iter += 1; |
| tokio::time::sleep(Duration::from_secs(1)).await; |
| |
| if iter % 2 == 0 { |
| reporter.set_serving::<GreeterServer<MyGreeter>>().await; |
| } else { |
| reporter.set_not_serving::<GreeterServer<MyGreeter>>().await; |
| }; |
| } |
| } |
| |
| #[tokio::main] |
| async fn main() -> Result<(), Box<dyn std::error::Error>> { |
| let (mut health_reporter, health_service) = tonic_health::server::health_reporter(); |
| health_reporter |
| .set_serving::<GreeterServer<MyGreeter>>() |
| .await; |
| |
| tokio::spawn(twiddle_service_status(health_reporter.clone())); |
| |
| let addr = "[::1]:50051".parse().unwrap(); |
| let greeter = MyGreeter::default(); |
| |
| println!("HealthServer + GreeterServer listening on {}", addr); |
| |
| Server::builder() |
| .add_service(health_service) |
| .add_service(GreeterServer::new(greeter)) |
| .serve(addr) |
| .await?; |
| |
| Ok(()) |
| } |