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 while let time = interval.tick().await { 69 let elapsed = time.duration_since(start); 70 let note = RouteNote { 71 location: Some(Point { 72 latitude: 409146138 + elapsed.as_secs() as i32, 73 longitude: -746188906, 74 }), 75 message: format!("at {:?}", elapsed), 76 }; 77 78 yield note; 79 } 80 }; 81 82 let response = client.route_chat(Request::new(outbound)).await?; 83 let mut inbound = response.into_inner(); 84 85 while let Some(note) = inbound.message().await? { 86 println!("NOTE = {:?}", note); 87 } 88 89 Ok(()) 90 } 91 92 #[tokio::main] 93 async fn main() -> Result<(), Box<dyn std::error::Error>> { 94 let mut client = RouteGuideClient::connect("http://[::1]:10000").await?; 95 96 println!("*** SIMPLE RPC ***"); 97 let response = client 98 .get_feature(Request::new(Point { 99 latitude: 409_146_138, 100 longitude: -746_188_906, 101 })) 102 .await?; 103 println!("RESPONSE = {:?}", response); 104 105 println!("\n*** SERVER STREAMING ***"); 106 print_features(&mut client).await?; 107 108 println!("\n*** CLIENT STREAMING ***"); 109 run_record_route(&mut client).await?; 110 111 println!("\n*** BIDIRECTIONAL STREAMING ***"); 112 run_route_chat(&mut client).await?; 113 114 Ok(()) 115 } 116 117 fn random_point(rng: &mut ThreadRng) -> Point { 118 let latitude = (rng.gen_range(0, 180) - 90) * 10_000_000; 119 let longitude = (rng.gen_range(0, 360) - 180) * 10_000_000; 120 Point { 121 latitude, 122 longitude, 123 } 124 } 125