github.com/stackb/rules_proto@v0.0.0-20240221195024-5428336c51f1/example/routeguide/cc/server.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 <algorithm> 20 #include <chrono> 21 #include <cmath> 22 #include <iostream> 23 #include <memory> 24 #include <string> 25 26 #include "helper.h" 27 28 #include "example/routeguide/routeguide.grpc.pb.h" 29 #include <grpc/grpc.h> 30 #include <grpcpp/security/server_credentials.h> 31 #include <grpcpp/server.h> 32 #include <grpcpp/server_builder.h> 33 #include <grpcpp/server_context.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::Server; 42 using grpc::ServerBuilder; 43 using grpc::ServerContext; 44 using grpc::ServerReader; 45 using grpc::ServerReaderWriter; 46 using grpc::ServerWriter; 47 using grpc::Status; 48 using std::chrono::system_clock; 49 50 float ConvertToRadians(float num) { return num * 3.1415926 / 180; } 51 52 // The formula is based on http://mathforum.org/library/drmath/view/51879.html 53 float GetDistance(const Point &start, const Point &end) { 54 const float kCoordFactor = 10000000.0; 55 float lat_1 = start.latitude() / kCoordFactor; 56 float lat_2 = end.latitude() / kCoordFactor; 57 float lon_1 = start.longitude() / kCoordFactor; 58 float lon_2 = end.longitude() / kCoordFactor; 59 float lat_rad_1 = ConvertToRadians(lat_1); 60 float lat_rad_2 = ConvertToRadians(lat_2); 61 float delta_lat_rad = ConvertToRadians(lat_2 - lat_1); 62 float delta_lon_rad = ConvertToRadians(lon_2 - lon_1); 63 64 float a = pow(sin(delta_lat_rad / 2), 2) + 65 cos(lat_rad_1) * cos(lat_rad_2) * pow(sin(delta_lon_rad / 2), 2); 66 float c = 2 * atan2(sqrt(a), sqrt(1 - a)); 67 int R = 6371000; // metres 68 69 return R * c; 70 } 71 72 std::string GetFeatureName(const Point &point, 73 const std::vector<Feature> &feature_list) { 74 for (const Feature &f : feature_list) { 75 if (f.location().latitude() == point.latitude() && 76 f.location().longitude() == point.longitude()) { 77 return f.name(); 78 } 79 } 80 return ""; 81 } 82 83 class RouteGuideImpl final : public RouteGuide::Service { 84 public: 85 explicit RouteGuideImpl(const std::string &db) { 86 example::routeguide::ParseDb(db, &feature_list_); 87 } 88 89 Status GetFeature(ServerContext *context, const Point *point, 90 Feature *feature) override { 91 feature->set_name(GetFeatureName(*point, feature_list_)); 92 feature->mutable_location()->CopyFrom(*point); 93 return Status::OK; 94 } 95 96 Status ListFeatures(ServerContext *context, const Rectangle *rectangle, 97 ServerWriter<Feature> *writer) override { 98 auto lo = rectangle->lo(); 99 auto hi = rectangle->hi(); 100 long left = (std::min)(lo.longitude(), hi.longitude()); 101 long right = (std::max)(lo.longitude(), hi.longitude()); 102 long top = (std::max)(lo.latitude(), hi.latitude()); 103 long bottom = (std::min)(lo.latitude(), hi.latitude()); 104 for (const Feature &f : feature_list_) { 105 if (f.location().longitude() >= left && 106 f.location().longitude() <= right && 107 f.location().latitude() >= bottom && f.location().latitude() <= top) { 108 writer->Write(f); 109 } 110 } 111 return Status::OK; 112 } 113 114 Status RecordRoute(ServerContext *context, ServerReader<Point> *reader, 115 RouteSummary *summary) override { 116 Point point; 117 int point_count = 0; 118 int feature_count = 0; 119 float distance = 0.0; 120 Point previous; 121 122 system_clock::time_point start_time = system_clock::now(); 123 while (reader->Read(&point)) { 124 point_count++; 125 if (!GetFeatureName(point, feature_list_).empty()) { 126 feature_count++; 127 } 128 if (point_count != 1) { 129 distance += GetDistance(previous, point); 130 } 131 previous = point; 132 } 133 system_clock::time_point end_time = system_clock::now(); 134 summary->set_point_count(point_count); 135 summary->set_feature_count(feature_count); 136 summary->set_distance(static_cast<long>(distance)); 137 auto secs = 138 std::chrono::duration_cast<std::chrono::seconds>(end_time - start_time); 139 summary->set_elapsed_time(secs.count()); 140 141 return Status::OK; 142 } 143 144 Status RouteChat(ServerContext *context, 145 ServerReaderWriter<RouteNote, RouteNote> *stream) override { 146 RouteNote note; 147 while (stream->Read(¬e)) { 148 std::unique_lock<std::mutex> lock(mu_); 149 for (const RouteNote &n : received_notes_) { 150 if (n.location().latitude() == note.location().latitude() && 151 n.location().longitude() == note.location().longitude()) { 152 stream->Write(n); 153 } 154 } 155 received_notes_.push_back(note); 156 } 157 158 return Status::OK; 159 } 160 161 private: 162 std::vector<Feature> feature_list_; 163 std::mutex mu_; 164 std::vector<RouteNote> received_notes_; 165 }; 166 167 void RunServer(const std::string &db_path) { 168 std::string server_address("0.0.0.0:50051"); 169 RouteGuideImpl service(db_path); 170 171 ServerBuilder builder; 172 builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); 173 builder.RegisterService(&service); 174 std::unique_ptr<Server> server(builder.BuildAndStart()); 175 std::cout << "Server listening on " << server_address << std::endl; 176 server->Wait(); 177 } 178 179 int main(int argc, char **argv) { 180 // Expect only arg: --db_path=path/to/route_guide_db.json. 181 std::string db = example::routeguide::GetDbFileContent(argc, argv); 182 RunServer(db); 183 184 return 0; 185 }