github.com/stackb/rules_proto@v0.0.0-20240221195024-5428336c51f1/example/routeguide/cc/client.cc (about) 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 "example/routeguide/routeguide.grpc.pb.h" 29 #include <grpc/grpc.h> 30 #include <grpcpp/channel.h> 31 #include <grpcpp/client_context.h> 32 #include <grpcpp/create_channel.h> 33 #include <grpcpp/security/credentials.h> 34 35 using example::routeguide::Feature; 36 using example::routeguide::Point; 37 using example::routeguide::Rectangle; 38 using example::routeguide::RouteGuide; 39 using example::routeguide::RouteNote; 40 using example::routeguide::RouteSummary; 41 using grpc::Channel; 42 using grpc::ClientContext; 43 using grpc::ClientReader; 44 using grpc::ClientReaderWriter; 45 using grpc::ClientWriter; 46 using grpc::Status; 47 48 Point MakePoint(long latitude, long longitude) { 49 Point p; 50 p.set_latitude(latitude); 51 p.set_longitude(longitude); 52 return p; 53 } 54 55 Feature MakeFeature(const std::string &name, long latitude, long longitude) { 56 Feature f; 57 f.set_name(name); 58 f.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); 59 return f; 60 } 61 62 RouteNote MakeRouteNote(const std::string &message, long latitude, 63 long longitude) { 64 RouteNote n; 65 n.set_message(message); 66 n.mutable_location()->CopyFrom(MakePoint(latitude, longitude)); 67 return n; 68 } 69 70 class RouteGuideClient { 71 public: 72 RouteGuideClient(std::shared_ptr<Channel> channel, const std::string &db) 73 : stub_(RouteGuide::NewStub(channel)) { 74 example::routeguide::ParseDb(db, &feature_list_); 75 } 76 77 void GetFeature() { 78 Point point; 79 Feature feature; 80 point = MakePoint(409146138, -746188906); 81 GetOneFeature(point, &feature); 82 point = MakePoint(0, 0); 83 GetOneFeature(point, &feature); 84 } 85 86 void ListFeatures() { 87 Rectangle rect; 88 Feature feature; 89 ClientContext context; 90 91 rect.mutable_lo()->set_latitude(400000000); 92 rect.mutable_lo()->set_longitude(-750000000); 93 rect.mutable_hi()->set_latitude(420000000); 94 rect.mutable_hi()->set_longitude(-730000000); 95 std::cout << "Looking for features between 40, -75 and 42, -73" 96 << std::endl; 97 98 std::unique_ptr<ClientReader<Feature>> reader( 99 stub_->ListFeatures(&context, rect)); 100 while (reader->Read(&feature)) { 101 std::cout << "Found feature called " << feature.name() << " at " 102 << feature.location().latitude() / kCoordFactor_ << ", " 103 << feature.location().longitude() / kCoordFactor_ << std::endl; 104 } 105 Status status = reader->Finish(); 106 if (status.ok()) { 107 std::cout << "ListFeatures rpc succeeded." << std::endl; 108 } else { 109 std::cout << "ListFeatures rpc failed." << std::endl; 110 } 111 } 112 113 void RecordRoute() { 114 Point point; 115 RouteSummary stats; 116 ClientContext context; 117 const int kPoints = 10; 118 unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); 119 120 std::default_random_engine generator(seed); 121 std::uniform_int_distribution<int> feature_distribution( 122 0, feature_list_.size() - 1); 123 std::uniform_int_distribution<int> delay_distribution(500, 1500); 124 125 std::unique_ptr<ClientWriter<Point>> writer( 126 stub_->RecordRoute(&context, &stats)); 127 for (int i = 0; i < kPoints; i++) { 128 const Feature &f = feature_list_[feature_distribution(generator)]; 129 std::cout << "Visiting point " << f.location().latitude() / kCoordFactor_ 130 << ", " << f.location().longitude() / kCoordFactor_ 131 << std::endl; 132 if (!writer->Write(f.location())) { 133 // Broken stream. 134 break; 135 } 136 std::this_thread::sleep_for( 137 std::chrono::milliseconds(delay_distribution(generator))); 138 } 139 writer->WritesDone(); 140 Status status = writer->Finish(); 141 if (status.ok()) { 142 std::cout << "Finished trip with " << stats.point_count() << " points\n" 143 << "Passed " << stats.feature_count() << " features\n" 144 << "Travelled " << stats.distance() << " meters\n" 145 << "It took " << stats.elapsed_time() << " seconds" 146 << std::endl; 147 } else { 148 std::cout << "RecordRoute rpc failed." << std::endl; 149 } 150 } 151 152 void RouteChat() { 153 ClientContext context; 154 155 std::shared_ptr<ClientReaderWriter<RouteNote, RouteNote>> stream( 156 stub_->RouteChat(&context)); 157 158 std::thread writer([stream]() { 159 std::vector<RouteNote> notes{MakeRouteNote("First message", 0, 0), 160 MakeRouteNote("Second message", 0, 1), 161 MakeRouteNote("Third message", 1, 0), 162 MakeRouteNote("Fourth message", 0, 0)}; 163 for (const RouteNote ¬e : notes) { 164 std::cout << "Sending message " << note.message() << " at " 165 << note.location().latitude() << ", " 166 << note.location().longitude() << std::endl; 167 stream->Write(note); 168 } 169 stream->WritesDone(); 170 }); 171 172 RouteNote server_note; 173 while (stream->Read(&server_note)) { 174 std::cout << "Got message " << server_note.message() << " at " 175 << server_note.location().latitude() << ", " 176 << server_note.location().longitude() << std::endl; 177 } 178 writer.join(); 179 Status status = stream->Finish(); 180 if (!status.ok()) { 181 std::cout << "RouteChat rpc failed." << std::endl; 182 } 183 } 184 185 private: 186 bool GetOneFeature(const Point &point, Feature *feature) { 187 ClientContext context; 188 Status status = stub_->GetFeature(&context, point, feature); 189 if (!status.ok()) { 190 std::cout << "GetFeature rpc failed." << std::endl; 191 return false; 192 } 193 if (!feature->has_location()) { 194 std::cout << "Server returns incomplete feature." << std::endl; 195 return false; 196 } 197 if (feature->name().empty()) { 198 std::cout << "Found no feature at " 199 << feature->location().latitude() / kCoordFactor_ << ", " 200 << feature->location().longitude() / kCoordFactor_ << std::endl; 201 } else { 202 std::cout << "Found feature called " << feature->name() << " at " 203 << feature->location().latitude() / kCoordFactor_ << ", " 204 << feature->location().longitude() / kCoordFactor_ << std::endl; 205 } 206 return true; 207 } 208 209 const float kCoordFactor_ = 10000000.0; 210 std::unique_ptr<RouteGuide::Stub> stub_; 211 std::vector<Feature> feature_list_; 212 }; 213 214 int main(int argc, char **argv) { 215 // Expect only arg: --db_path=path/to/route_guide_db.json. 216 std::string db = example::routeguide::GetDbFileContent(argc, argv); 217 RouteGuideClient guide( 218 grpc::CreateChannel("localhost:50051", 219 grpc::InsecureChannelCredentials()), 220 db); 221 222 std::cout << "-------------- GetFeature --------------" << std::endl; 223 guide.GetFeature(); 224 std::cout << "-------------- ListFeatures --------------" << std::endl; 225 guide.ListFeatures(); 226 std::cout << "-------------- RecordRoute --------------" << std::endl; 227 guide.RecordRoute(); 228 std::cout << "-------------- RouteChat --------------" << std::endl; 229 guide.RouteChat(); 230 231 return 0; 232 }