xref: /tonic/examples/src/uds/server.rs (revision da92dbf8)
1 #![cfg_attr(not(unix), allow(unused_imports))]
2 
3 use futures::stream::TryStreamExt;
4 use std::path::Path;
5 #[cfg(unix)]
6 use tokio::net::UnixListener;
7 use tonic::{transport::Server, Request, Response, Status};
8 
9 pub mod hello_world {
10     tonic::include_proto!("helloworld");
11 }
12 
13 use hello_world::{
14     greeter_server::{Greeter, GreeterServer},
15     HelloReply, HelloRequest,
16 };
17 
18 #[derive(Default)]
19 pub struct MyGreeter {}
20 
21 #[tonic::async_trait]
22 impl Greeter for MyGreeter {
23     async fn say_hello(
24         &self,
25         request: Request<HelloRequest>,
26     ) -> Result<Response<HelloReply>, Status> {
27         println!("Got a request: {:?}", request);
28 
29         let reply = hello_world::HelloReply {
30             message: format!("Hello {}!", request.into_inner().name),
31         };
32         Ok(Response::new(reply))
33     }
34 }
35 
36 #[cfg(unix)]
37 #[tokio::main]
38 async fn main() -> Result<(), Box<dyn std::error::Error>> {
39     let path = "/tmp/tonic/helloworld";
40 
41     tokio::fs::create_dir_all(Path::new(path).parent().unwrap()).await?;
42 
43     let mut uds = UnixListener::bind(path)?;
44 
45     let greeter = MyGreeter::default();
46 
47     Server::builder()
48         .add_service(GreeterServer::new(greeter))
49         .serve_with_incoming(uds.incoming().map_ok(unix::UnixStream))
50         .await?;
51 
52     Ok(())
53 }
54 
55 #[cfg(unix)]
56 mod unix {
57     use std::{
58         pin::Pin,
59         task::{Context, Poll},
60     };
61 
62     use tokio::io::{AsyncRead, AsyncWrite};
63     use tonic::transport::server::Connected;
64 
65     #[derive(Debug)]
66     pub struct UnixStream(pub tokio::net::UnixStream);
67 
68     impl Connected for UnixStream {}
69 
70     impl AsyncRead for UnixStream {
71         fn poll_read(
72             mut self: Pin<&mut Self>,
73             cx: &mut Context<'_>,
74             buf: &mut [u8],
75         ) -> Poll<std::io::Result<usize>> {
76             Pin::new(&mut self.0).poll_read(cx, buf)
77         }
78     }
79 
80     impl AsyncWrite for UnixStream {
81         fn poll_write(
82             mut self: Pin<&mut Self>,
83             cx: &mut Context<'_>,
84             buf: &[u8],
85         ) -> Poll<std::io::Result<usize>> {
86             Pin::new(&mut self.0).poll_write(cx, buf)
87         }
88 
89         fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
90             Pin::new(&mut self.0).poll_flush(cx)
91         }
92 
93         fn poll_shutdown(
94             mut self: Pin<&mut Self>,
95             cx: &mut Context<'_>,
96         ) -> Poll<std::io::Result<()>> {
97             Pin::new(&mut self.0).poll_shutdown(cx)
98         }
99     }
100 }
101 
102 #[cfg(not(unix))]
103 fn main() {
104     panic!("The `uds` example only works on unix systems!");
105 }
106