xref: /aosp_15_r20/external/grpc-grpc/examples/cpp/route_guide/route_guide_client.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <chrono>
20 #include <iostream>
21 #include <memory>
22 #include <random>
23 #include <string>
24 #include <thread>
25 
26 #include "helper.h"
27 
28 #include <grpc/grpc.h>
29 #include <grpcpp/channel.h>
30 #include <grpcpp/client_context.h>
31 #include <grpcpp/create_channel.h>
32 #include <grpcpp/security/credentials.h>
33 #ifdef BAZEL_BUILD
34 #include "examples/protos/route_guide.grpc.pb.h"
35 #else
36 #include "route_guide.grpc.pb.h"
37 #endif
38 
39 using grpc::Channel;
40 using grpc::ClientContext;
41 using grpc::ClientReader;
42 using grpc::ClientReaderWriter;
43 using grpc::ClientWriter;
44 using grpc::Status;
45 using routeguide::Feature;
46 using routeguide::Point;
47 using routeguide::Rectangle;
48 using routeguide::RouteGuide;
49 using routeguide::RouteNote;
50 using routeguide::RouteSummary;
51 
MakePoint(long latitude,long longitude)52 Point MakePoint(long latitude, long longitude) {
53   Point p;
54   p.set_latitude(latitude);
55   p.set_longitude(longitude);
56   return p;
57 }
58 
MakeFeature(const std::string & name,long latitude,long longitude)59 Feature MakeFeature(const std::string& name, long latitude, long longitude) {
60   Feature f;
61   f.set_name(name);
62   f.mutable_location()->CopyFrom(MakePoint(latitude, longitude));
63   return f;
64 }
65 
MakeRouteNote(const std::string & message,long latitude,long longitude)66 RouteNote MakeRouteNote(const std::string& message, long latitude,
67                         long longitude) {
68   RouteNote n;
69   n.set_message(message);
70   n.mutable_location()->CopyFrom(MakePoint(latitude, longitude));
71   return n;
72 }
73 
74 class RouteGuideClient {
75  public:
RouteGuideClient(std::shared_ptr<Channel> channel,const std::string & db)76   RouteGuideClient(std::shared_ptr<Channel> channel, const std::string& db)
77       : stub_(RouteGuide::NewStub(channel)) {
78     routeguide::ParseDb(db, &feature_list_);
79   }
80 
GetFeature()81   void GetFeature() {
82     Point point;
83     Feature feature;
84     point = MakePoint(409146138, -746188906);
85     GetOneFeature(point, &feature);
86     point = MakePoint(0, 0);
87     GetOneFeature(point, &feature);
88   }
89 
ListFeatures()90   void ListFeatures() {
91     routeguide::Rectangle rect;
92     Feature feature;
93     ClientContext context;
94 
95     rect.mutable_lo()->set_latitude(400000000);
96     rect.mutable_lo()->set_longitude(-750000000);
97     rect.mutable_hi()->set_latitude(420000000);
98     rect.mutable_hi()->set_longitude(-730000000);
99     std::cout << "Looking for features between 40, -75 and 42, -73"
100               << std::endl;
101 
102     std::unique_ptr<ClientReader<Feature> > reader(
103         stub_->ListFeatures(&context, rect));
104     while (reader->Read(&feature)) {
105       std::cout << "Found feature called " << feature.name() << " at "
106                 << feature.location().latitude() / kCoordFactor_ << ", "
107                 << feature.location().longitude() / kCoordFactor_ << std::endl;
108     }
109     Status status = reader->Finish();
110     if (status.ok()) {
111       std::cout << "ListFeatures rpc succeeded." << std::endl;
112     } else {
113       std::cout << "ListFeatures rpc failed." << std::endl;
114     }
115   }
116 
RecordRoute()117   void RecordRoute() {
118     Point point;
119     RouteSummary stats;
120     ClientContext context;
121     const int kPoints = 10;
122     unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
123 
124     std::default_random_engine generator(seed);
125     std::uniform_int_distribution<int> feature_distribution(
126         0, feature_list_.size() - 1);
127     std::uniform_int_distribution<int> delay_distribution(500, 1500);
128 
129     std::unique_ptr<ClientWriter<Point> > writer(
130         stub_->RecordRoute(&context, &stats));
131     for (int i = 0; i < kPoints; i++) {
132       const Feature& f = feature_list_[feature_distribution(generator)];
133       std::cout << "Visiting point " << f.location().latitude() / kCoordFactor_
134                 << ", " << f.location().longitude() / kCoordFactor_
135                 << std::endl;
136       if (!writer->Write(f.location())) {
137         // Broken stream.
138         break;
139       }
140       std::this_thread::sleep_for(
141           std::chrono::milliseconds(delay_distribution(generator)));
142     }
143     writer->WritesDone();
144     Status status = writer->Finish();
145     if (status.ok()) {
146       std::cout << "Finished trip with " << stats.point_count() << " points\n"
147                 << "Passed " << stats.feature_count() << " features\n"
148                 << "Travelled " << stats.distance() << " meters\n"
149                 << "It took " << stats.elapsed_time() << " seconds"
150                 << std::endl;
151     } else {
152       std::cout << "RecordRoute rpc failed." << std::endl;
153     }
154   }
155 
RouteChat()156   void RouteChat() {
157     ClientContext context;
158 
159     std::shared_ptr<ClientReaderWriter<RouteNote, RouteNote> > stream(
160         stub_->RouteChat(&context));
161 
162     std::thread writer([stream]() {
163       std::vector<RouteNote> notes{MakeRouteNote("First message", 0, 0),
164                                    MakeRouteNote("Second message", 0, 1),
165                                    MakeRouteNote("Third message", 1, 0),
166                                    MakeRouteNote("Fourth message", 0, 0)};
167       for (const RouteNote& note : notes) {
168         std::cout << "Sending message " << note.message() << " at "
169                   << note.location().latitude() << ", "
170                   << note.location().longitude() << std::endl;
171         stream->Write(note);
172       }
173       stream->WritesDone();
174     });
175 
176     RouteNote server_note;
177     while (stream->Read(&server_note)) {
178       std::cout << "Got message " << server_note.message() << " at "
179                 << server_note.location().latitude() << ", "
180                 << server_note.location().longitude() << std::endl;
181     }
182     writer.join();
183     Status status = stream->Finish();
184     if (!status.ok()) {
185       std::cout << "RouteChat rpc failed." << std::endl;
186     }
187   }
188 
189  private:
GetOneFeature(const Point & point,Feature * feature)190   bool GetOneFeature(const Point& point, Feature* feature) {
191     ClientContext context;
192     Status status = stub_->GetFeature(&context, point, feature);
193     if (!status.ok()) {
194       std::cout << "GetFeature rpc failed." << std::endl;
195       return false;
196     }
197     if (!feature->has_location()) {
198       std::cout << "Server returns incomplete feature." << std::endl;
199       return false;
200     }
201     if (feature->name().empty()) {
202       std::cout << "Found no feature at "
203                 << feature->location().latitude() / kCoordFactor_ << ", "
204                 << feature->location().longitude() / kCoordFactor_ << std::endl;
205     } else {
206       std::cout << "Found feature called " << feature->name() << " at "
207                 << feature->location().latitude() / kCoordFactor_ << ", "
208                 << feature->location().longitude() / kCoordFactor_ << std::endl;
209     }
210     return true;
211   }
212 
213   const float kCoordFactor_ = 10000000.0;
214   std::unique_ptr<RouteGuide::Stub> stub_;
215   std::vector<Feature> feature_list_;
216 };
217 
main(int argc,char ** argv)218 int main(int argc, char** argv) {
219   // Expect only arg: --db_path=path/to/route_guide_db.json.
220   std::string db = routeguide::GetDbFileContent(argc, argv);
221   RouteGuideClient guide(
222       grpc::CreateChannel("localhost:50051",
223                           grpc::InsecureChannelCredentials()),
224       db);
225 
226   std::cout << "-------------- GetFeature --------------" << std::endl;
227   guide.GetFeature();
228   std::cout << "-------------- ListFeatures --------------" << std::endl;
229   guide.ListFeatures();
230   std::cout << "-------------- RecordRoute --------------" << std::endl;
231   guide.RecordRoute();
232   std::cout << "-------------- RouteChat --------------" << std::endl;
233   guide.RouteChat();
234 
235   return 0;
236 }
237