/// <summary> /// Gets a stream of points, and responds with statistics about the "trip": number of points, /// number of known features visited, total distance traveled, and total time spent. /// </summary> public async Task <RouteSummary> RecordRoute(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader <Point> requestStream) { int pointCount = 0; int featureCount = 0; int distance = 0; Point previous = null; var stopwatch = new Stopwatch(); stopwatch.Start(); while (await requestStream.MoveNext()) { var point = requestStream.Current; pointCount++; if (RouteGuideUtil.Exists(CheckFeature(point))) { featureCount++; } if (previous != null) { distance += (int)CalcDistance(previous, point); } previous = point; } stopwatch.Stop(); return(RouteSummary.CreateBuilder().SetPointCount(pointCount) .SetFeatureCount(featureCount).SetDistance(distance) .SetElapsedTime((int)(stopwatch.ElapsedMilliseconds / 1000)).Build()); }
/// <summary> /// Blocking unary call example. Calls GetFeature and prints the response. /// </summary> public void GetFeature(int lat, int lon) { try { Log("*** GetFeature: lat={0} lon={1}", lat, lon); Point request = Point.CreateBuilder().SetLatitude(lat).SetLongitude(lon).Build(); Feature feature = client.GetFeature(request); if (RouteGuideUtil.Exists(feature)) { Log("Found feature called \"{0}\" at {1}, {2}", feature.Name, RouteGuideUtil.GetLatitude(feature.Location), RouteGuideUtil.GetLongitude(feature.Location)); } else { Log("Found no feature at {0}, {1}", RouteGuideUtil.GetLatitude(feature.Location), RouteGuideUtil.GetLongitude(feature.Location)); } } catch (RpcException e) { Log("RPC failed " + e); throw e; } }
static void Main(string[] args) { GrpcEnvironment.Initialize(); using (Channel channel = new Channel("127.0.0.1:50052")) { var client = new RouteGuideClient(RouteGuide.NewStub(channel)); // Looking for a valid feature client.GetFeature(409146138, -746188906); // Feature missing. client.GetFeature(0, 0); // Looking for features between 40, -75 and 42, -73. client.ListFeatures(400000000, -750000000, 420000000, -730000000).Wait(); // Record a few randomly selected points from the features file. client.RecordRoute(RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile), 10).Wait(); // Send and receive some notes. client.RouteChat().Wait(); } GrpcEnvironment.Shutdown(); }
/// <summary> /// Calculate the distance between two points using the "haversine" formula. /// This code was taken from http://www.movable-type.co.uk/scripts/latlong.html. /// </summary> /// <param name="start">the starting point</param> /// <param name="end">the end point</param> /// <returns>the distance between the points in meters</returns> private static double CalcDistance(Point start, Point end) { double lat1 = RouteGuideUtil.GetLatitude(start); double lat2 = RouteGuideUtil.GetLatitude(end); double lon1 = RouteGuideUtil.GetLongitude(start); double lon2 = RouteGuideUtil.GetLongitude(end); int r = 6371000; // metres double φ1 = ToRadians(lat1); double φ2 = ToRadians(lat2); double Δφ = ToRadians(lat2 - lat1); double Δλ = ToRadians(lon2 - lon1); double a = Math.Sin(Δφ / 2) * Math.Sin(Δφ / 2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2); double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); return(r * c); }
static void Main(string[] args) { var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile); GrpcEnvironment.Initialize(); Server server = new Server(); server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features))); int port = server.AddListeningPort("localhost", 50052); server.Start(); Console.WriteLine("RouteGuide server listening on port " + port); Console.WriteLine("Press any key to stop the server..."); Console.ReadKey(); server.ShutdownAsync().Wait(); GrpcEnvironment.Shutdown(); }
/// <summary> /// Gets all features contained within the given bounding rectangle. /// </summary> public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request, Grpc.Core.IServerStreamWriter <Feature> responseStream) { int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude); int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude); int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude); int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude); foreach (var feature in features) { if (!RouteGuideUtil.Exists(feature)) { continue; } int lat = feature.Location.Latitude; int lon = feature.Location.Longitude; if (lon >= left && lon <= right && lat >= bottom && lat <= top) { await responseStream.WriteAsync(feature); } } }
/// <summary> /// Client-streaming example. Sends numPoints randomly chosen points from features /// with a variable delay in between. Prints the statistics when they are sent from the server. /// </summary> public async Task RecordRoute(List <Feature> features, int numPoints) { try { Log("*** RecordRoute"); using (var call = client.RecordRoute()) { // Send numPoints points randomly selected from the features list. StringBuilder numMsg = new StringBuilder(); Random rand = new Random(); for (int i = 0; i < numPoints; ++i) { int index = rand.Next(features.Count); Point point = features[index].Location; Log("Visiting point {0}, {1}", RouteGuideUtil.GetLatitude(point), RouteGuideUtil.GetLongitude(point)); await call.RequestStream.WriteAsync(point); // A bit of delay before sending the next one. await Task.Delay(rand.Next(1000) + 500); } await call.RequestStream.CompleteAsync(); RouteSummary summary = await call.Result; Log("Finished trip with {0} points. Passed {1} features. " + "Travelled {2} meters. It took {3} seconds.", summary.PointCount, summary.FeatureCount, summary.Distance, summary.ElapsedTime); Log("Finished RecordRoute"); } } catch (RpcException e) { Log("RPC failed", e); throw e; } }