1 use std::error::Error; 2 use std::time::Duration; 3 4 use futures::stream; 5 use rand::rngs::ThreadRng; 6 use rand::Rng; 7 use tokio::time; 8 use tonic::transport::Channel; 9 use tonic::Request; 10 11 use routeguide::route_guide_client::RouteGuideClient; 12 use routeguide::{Point, Rectangle, RouteNote}; 13 14 pub mod routeguide { 15 tonic::include_proto!("routeguide"); 16 } 17 18 async fn print_features(client: &mut RouteGuideClient<Channel>) -> Result<(), Box<dyn Error>> { 19 let rectangle = Rectangle { 20 lo: Some(Point { 21 latitude: 400_000_000, 22 longitude: -750_000_000, 23 }), 24 hi: Some(Point { 25 latitude: 420_000_000, 26 longitude: -730_000_000, 27 }), 28 }; 29 30 let mut stream = client 31 .list_features(Request::new(rectangle)) 32 .await? 33 .into_inner(); 34 35 while let Some(feature) = stream.message().await? { 36 println!("NOTE = {:?}", feature); 37 } 38 39 Ok(()) 40 } 41 42 async fn run_record_route(client: &mut RouteGuideClient<Channel>) -> Result<(), Box<dyn Error>> { 43 let mut rng = rand::thread_rng(); 44 let point_count: i32 = rng.gen_range(2..100); 45 46 let mut points = vec![]; 47 for _ in 0..=point_count { 48 points.push(random_point(&mut rng)) 49 } 50 51 println!("Traversing {} points", points.len()); 52 let request = Request::new(stream::iter(points)); 53 54 match client.record_route(request).await { 55 Ok(response) => println!("SUMMARY: {:?}", response.into_inner()), 56 Err(e) => println!("something went wrong: {:?}", e), 57 } 58 59 Ok(()) 60 } 61 62 async fn run_route_chat(client: &mut RouteGuideClient<Channel>) -> Result<(), Box<dyn Error>> { 63 let start = time::Instant::now(); 64 65 let outbound = async_stream::stream! { 66 let mut interval = time::interval(Duration::from_secs(1)); 67 68 loop { 69 let time = interval.tick().await; 70 let elapsed = time.duration_since(start); 71 let note = RouteNote { 72 location: Some(Point { 73 latitude: 409146138 + elapsed.as_secs() as i32, 74 longitude: -746188906, 75 }), 76 message: format!("at {:?}", elapsed), 77 }; 78 79 yield note; 80 } 81 }; 82 83 let response = client.route_chat(Request::new(outbound)).await?; 84 let mut inbound = response.into_inner(); 85 86 while let Some(note) = inbound.message().await? { 87 println!("NOTE = {:?}", note); 88 } 89 90 Ok(()) 91 } 92 93 #[tokio::main] 94 async fn main() -> Result<(), Box<dyn std::error::Error>> { 95 let mut client = RouteGuideClient::connect("http://[::1]:10000").await?; 96 97 println!("*** SIMPLE RPC ***"); 98 let response = client 99 .get_feature(Request::new(Point { 100 latitude: 409_146_138, 101 longitude: -746_188_906, 102 })) 103 .await?; 104 println!("RESPONSE = {:?}", response); 105 106 println!("\n*** SERVER STREAMING ***"); 107 print_features(&mut client).await?; 108 109 println!("\n*** CLIENT STREAMING ***"); 110 run_record_route(&mut client).await?; 111 112 println!("\n*** BIDIRECTIONAL STREAMING ***"); 113 run_route_chat(&mut client).await?; 114 115 Ok(()) 116 } 117 118 fn random_point(rng: &mut ThreadRng) -> Point { 119 let latitude = (rng.gen_range(0..180) - 90) * 10_000_000; 120 let longitude = (rng.gen_range(0..360) - 180) * 10_000_000; 121 Point { 122 latitude, 123 longitude, 124 } 125 } 126