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