1 use tonic::{ 2 transport::{Endpoint, Server, Uri}, 3 Request, Response, Status, 4 }; 5 use tower::service_fn; 6 7 pub mod hello_world { 8 tonic::include_proto!("helloworld"); 9 } 10 11 use hello_world::{ 12 greeter_client::GreeterClient, 13 greeter_server::{Greeter, GreeterServer}, 14 HelloReply, HelloRequest, 15 }; 16 17 #[tokio::main] 18 async fn main() -> Result<(), Box<dyn std::error::Error>> { 19 let (client, server) = tokio::io::duplex(1024); 20 21 let greeter = MyGreeter::default(); 22 23 tokio::spawn(async move { 24 Server::builder() 25 .add_service(GreeterServer::new(greeter)) 26 .serve_with_incoming(futures::stream::iter(vec![Ok::<_, std::io::Error>(server)])) 27 .await 28 }); 29 30 // Move client to an option so we can _move_ the inner value 31 // on the first attempt to connect. All other attempts will fail. 32 let mut client = Some(client); 33 let channel = Endpoint::try_from("http://[::]:50051")? 34 .connect_with_connector(service_fn(move |_: Uri| { 35 let client = client.take(); 36 37 async move { 38 if let Some(client) = client { 39 Ok(client) 40 } else { 41 Err(std::io::Error::new( 42 std::io::ErrorKind::Other, 43 "Client already taken", 44 )) 45 } 46 } 47 })) 48 .await?; 49 50 let mut client = GreeterClient::new(channel); 51 52 let request = tonic::Request::new(HelloRequest { 53 name: "Tonic".into(), 54 }); 55 56 let response = client.say_hello(request).await?; 57 58 println!("RESPONSE={:?}", response); 59 60 Ok(()) 61 } 62 63 #[derive(Default)] 64 pub struct MyGreeter {} 65 66 #[tonic::async_trait] 67 impl Greeter for MyGreeter { 68 async fn say_hello( 69 &self, 70 request: Request<HelloRequest>, 71 ) -> Result<Response<HelloReply>, Status> { 72 println!("Got a request: {:?}", request); 73 74 let reply = hello_world::HelloReply { 75 message: format!("Hello {}!", request.into_inner().name), 76 }; 77 Ok(Response::new(reply)) 78 } 79 } 80