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