1 pub mod pb {
2 tonic::include_proto!("/grpc.examples.unaryecho");
3 }
4
5 use pb::{EchoRequest, EchoResponse};
6 use tonic::{
7 transport::{
8 server::{TcpConnectInfo, TlsConnectInfo},
9 Identity, Server, ServerTlsConfig,
10 },
11 Request, Response, Status,
12 };
13
14 type EchoResult<T> = Result<Response<T>, Status>;
15
16 #[derive(Default)]
17 pub struct EchoServer {}
18
19 #[tonic::async_trait]
20 impl pb::echo_server::Echo for EchoServer {
unary_echo(&self, request: Request<EchoRequest>) -> EchoResult<EchoResponse>21 async fn unary_echo(&self, request: Request<EchoRequest>) -> EchoResult<EchoResponse> {
22 let conn_info = request
23 .extensions()
24 .get::<TlsConnectInfo<TcpConnectInfo>>()
25 .unwrap();
26 println!(
27 "Got a request from {:?} with info {:?}",
28 request.remote_addr(),
29 conn_info
30 );
31
32 let message = request.into_inner().message;
33 Ok(Response::new(EchoResponse { message }))
34 }
35 }
36
37 #[tokio::main]
main() -> Result<(), Box<dyn std::error::Error>>38 async fn main() -> Result<(), Box<dyn std::error::Error>> {
39 let data_dir = std::path::PathBuf::from_iter([std::env!("CARGO_MANIFEST_DIR"), "data"]);
40 let cert = std::fs::read_to_string(data_dir.join("tls/server.pem"))?;
41 let key = std::fs::read_to_string(data_dir.join("tls/server.key"))?;
42
43 let identity = Identity::from_pem(cert, key);
44
45 let addr = "[::1]:50051".parse().unwrap();
46 let server = EchoServer::default();
47
48 Server::builder()
49 .tls_config(ServerTlsConfig::new().identity(identity))?
50 .add_service(pb::echo_server::EchoServer::new(server))
51 .serve(addr)
52 .await?;
53
54 Ok(())
55 }
56