route_guide_client.cc 7.5 KB

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