1 pub mod pb {
2     tonic::include_proto!("grpc.examples.unaryecho");
3 }
4 
5 use std::net::SocketAddr;
6 use tokio::sync::mpsc;
7 use tonic::{transport::Server, Request, Response, Status};
8 
9 use pb::{EchoRequest, EchoResponse};
10 
11 type EchoResult<T> = Result<Response<T>, Status>;
12 
13 #[derive(Debug)]
14 pub struct EchoServer {
15     addr: SocketAddr,
16 }
17 
18 #[tonic::async_trait]
19 impl pb::echo_server::Echo for EchoServer {
unary_echo(&self, request: Request<EchoRequest>) -> EchoResult<EchoResponse>20     async fn unary_echo(&self, request: Request<EchoRequest>) -> EchoResult<EchoResponse> {
21         let message = format!("{} (from {})", request.into_inner().message, self.addr);
22 
23         Ok(Response::new(EchoResponse { message }))
24     }
25 }
26 
27 #[tokio::main]
main() -> Result<(), Box<dyn std::error::Error>>28 async fn main() -> Result<(), Box<dyn std::error::Error>> {
29     let addrs = ["[::1]:50051", "[::1]:50052"];
30 
31     let (tx, mut rx) = mpsc::unbounded_channel();
32 
33     for addr in &addrs {
34         let addr = addr.parse()?;
35         let tx = tx.clone();
36 
37         let server = EchoServer { addr };
38         let serve = Server::builder()
39             .add_service(pb::echo_server::EchoServer::new(server))
40             .serve(addr);
41 
42         tokio::spawn(async move {
43             if let Err(e) = serve.await {
44                 eprintln!("Error = {:?}", e);
45             }
46 
47             tx.send(()).unwrap();
48         });
49     }
50 
51     rx.recv().await;
52 
53     Ok(())
54 }
55