aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/cpp/route_guide
diff options
context:
space:
mode:
authorGravatar Stanley Cheung <stanleycheung@google.com>2015-08-27 14:00:20 -0700
committerGravatar Stanley Cheung <stanleycheung@google.com>2015-08-27 14:00:20 -0700
commit20fa6693f3836bf1418176ec78b26feaf51a369d (patch)
tree5975f66d7c6eb447baeea97fb62cdffa19d5c2e5 /examples/cpp/route_guide
parentb2bea23365acb0bcc1b5adba2d5b2fa5a22eb872 (diff)
move examples to correct locations
Diffstat (limited to 'examples/cpp/route_guide')
-rw-r--r--examples/cpp/route_guide/Makefile113
-rw-r--r--examples/cpp/route_guide/helper.cc178
-rw-r--r--examples/cpp/route_guide/helper.h50
-rw-r--r--examples/cpp/route_guide/route_guide_client.cc252
-rw-r--r--examples/cpp/route_guide/route_guide_db.json601
-rw-r--r--examples/cpp/route_guide/route_guide_server.cc202
6 files changed, 1396 insertions, 0 deletions
diff --git a/examples/cpp/route_guide/Makefile b/examples/cpp/route_guide/Makefile
new file mode 100644
index 0000000000..b906177af3
--- /dev/null
+++ b/examples/cpp/route_guide/Makefile
@@ -0,0 +1,113 @@
+#
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+CXX = g++
+CPPFLAGS += -I/usr/local/include -pthread
+CXXFLAGS += -std=c++11
+LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lgpr -lprotobuf -lpthread -ldl
+PROTOC = protoc
+GRPC_CPP_PLUGIN = grpc_cpp_plugin
+GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
+
+PROTOS_PATH = ../../protos
+
+vpath %.proto $(PROTOS_PATH)
+
+all: system-check route_guide_client route_guide_server
+
+route_guide_client: route_guide.pb.o route_guide.grpc.pb.o route_guide_client.o helper.o
+ $(CXX) $^ $(LDFLAGS) -o $@
+
+route_guide_server: route_guide.pb.o route_guide.grpc.pb.o route_guide_server.o helper.o
+ $(CXX) $^ $(LDFLAGS) -o $@
+
+%.grpc.pb.cc: %.proto
+ $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
+
+%.pb.cc: %.proto
+ $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<
+
+clean:
+ rm -f *.o *.pb.cc *.pb.h route_guide_client route_guide_server
+
+
+# The following is to test your system and ensure a smoother experience.
+# They are by no means necessary to actually compile a grpc-enabled software.
+
+PROTOC_CMD = which $(PROTOC)
+PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3
+PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN)
+HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false)
+ifeq ($(HAS_PROTOC),true)
+HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false)
+endif
+HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false)
+
+SYSTEM_OK = false
+ifeq ($(HAS_VALID_PROTOC),true)
+ifeq ($(HAS_PLUGIN),true)
+SYSTEM_OK = true
+endif
+endif
+
+system-check:
+ifneq ($(HAS_VALID_PROTOC),true)
+ @echo " DEPENDENCY ERROR"
+ @echo
+ @echo "You don't have protoc 3.0.0 installed in your path."
+ @echo "Please install Google protocol buffers 3.0.0 and its compiler."
+ @echo "You can find it here:"
+ @echo
+ @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-alpha-1"
+ @echo
+ @echo "Here is what I get when trying to evaluate your version of protoc:"
+ @echo
+ -$(PROTOC) --version
+ @echo
+ @echo
+endif
+ifneq ($(HAS_PLUGIN),true)
+ @echo " DEPENDENCY ERROR"
+ @echo
+ @echo "You don't have the grpc c++ protobuf plugin installed in your path."
+ @echo "Please install grpc. You can find it here:"
+ @echo
+ @echo " https://github.com/grpc/grpc"
+ @echo
+ @echo "Here is what I get when trying to detect if you have the plugin:"
+ @echo
+ -which $(GRPC_CPP_PLUGIN)
+ @echo
+ @echo
+endif
+ifneq ($(SYSTEM_OK),true)
+ @false
+endif
diff --git a/examples/cpp/route_guide/helper.cc b/examples/cpp/route_guide/helper.cc
new file mode 100644
index 0000000000..c2415afdf7
--- /dev/null
+++ b/examples/cpp/route_guide/helper.cc
@@ -0,0 +1,178 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <algorithm>
+#include <cctype>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+#include "route_guide.grpc.pb.h"
+
+namespace examples {
+
+std::string GetDbFileContent(int argc, char** argv) {
+ std::string db_path;
+ std::string arg_str("--db_path");
+ if (argc > 1) {
+ std::string argv_1 = argv[1];
+ size_t start_position = argv_1.find(arg_str);
+ if (start_position != std::string::npos) {
+ start_position += arg_str.size();
+ if (argv_1[start_position] == ' ' ||
+ argv_1[start_position] == '=') {
+ db_path = argv_1.substr(start_position + 1);
+ }
+ }
+ } else {
+ db_path = "route_guide_db.json";
+ }
+ std::ifstream db_file(db_path);
+ if (!db_file.is_open()) {
+ std::cout << "Failed to open " << db_path << std::endl;
+ return "";
+ }
+ std::stringstream db;
+ db << db_file.rdbuf();
+ return db.str();
+}
+
+// A simple parser for the json db file. It requires the db file to have the
+// exact form of [{"location": { "latitude": 123, "longitude": 456}, "name":
+// "the name can be empty" }, { ... } ... The spaces will be stripped.
+class Parser {
+ public:
+ explicit Parser(const std::string& db) : db_(db) {
+ // Remove all spaces.
+ db_.erase(
+ std::remove_if(db_.begin(), db_.end(), isspace),
+ db_.end());
+ if (!Match("[")) {
+ SetFailedAndReturnFalse();
+ }
+ }
+
+ bool Finished() {
+ return current_ >= db_.size();
+ }
+
+ bool TryParseOne(Feature* feature) {
+ if (failed_ || Finished() || !Match("{")) {
+ return SetFailedAndReturnFalse();
+ }
+ if (!Match(location_) || !Match("{") || !Match(latitude_)) {
+ return SetFailedAndReturnFalse();
+ }
+ long temp = 0;
+ ReadLong(&temp);
+ feature->mutable_location()->set_latitude(temp);
+ if (!Match(",") || !Match(longitude_)) {
+ return SetFailedAndReturnFalse();
+ }
+ ReadLong(&temp);
+ feature->mutable_location()->set_longitude(temp);
+ if (!Match("},") || !Match(name_) || !Match("\"")) {
+ return SetFailedAndReturnFalse();
+ }
+ size_t name_start = current_;
+ while (current_ != db_.size() && db_[current_++] != '"') {
+ }
+ if (current_ == db_.size()) {
+ return SetFailedAndReturnFalse();
+ }
+ feature->set_name(db_.substr(name_start, current_-name_start-1));
+ if (!Match("},")) {
+ if (db_[current_ - 1] == ']' && current_ == db_.size()) {
+ return true;
+ }
+ return SetFailedAndReturnFalse();
+ }
+ return true;
+ }
+
+ private:
+
+ bool SetFailedAndReturnFalse() {
+ failed_ = true;
+ return false;
+ }
+
+ bool Match(const std::string& prefix) {
+ bool eq = db_.substr(current_, prefix.size()) == prefix;
+ current_ += prefix.size();
+ return eq;
+ }
+
+ void ReadLong(long* l) {
+ size_t start = current_;
+ while (current_ != db_.size() && db_[current_] != ',' && db_[current_] != '}') {
+ current_++;
+ }
+ // It will throw an exception if fails.
+ *l = std::stol(db_.substr(start, current_ - start));
+ }
+
+ bool failed_ = false;
+ std::string db_;
+ size_t current_ = 0;
+ const std::string location_ = "\"location\":";
+ const std::string latitude_ = "\"latitude\":";
+ const std::string longitude_ = "\"longitude\":";
+ const std::string name_ = "\"name\":";
+};
+
+void ParseDb(const std::string& db, std::vector<Feature>* feature_list) {
+ feature_list->clear();
+ std::string db_content(db);
+ db_content.erase(
+ std::remove_if(db_content.begin(), db_content.end(), isspace),
+ db_content.end());
+
+ Parser parser(db_content);
+ Feature feature;
+ while (!parser.Finished()) {
+ feature_list->push_back(Feature());
+ if (!parser.TryParseOne(&feature_list->back())) {
+ std::cout << "Error parsing the db file";
+ feature_list->clear();
+ break;
+ }
+ }
+ std::cout << "DB parsed, loaded " << feature_list->size()
+ << " features." << std::endl;
+}
+
+
+} // namespace examples
+
diff --git a/examples/cpp/route_guide/helper.h b/examples/cpp/route_guide/helper.h
new file mode 100644
index 0000000000..65c93c1d34
--- /dev/null
+++ b/examples/cpp/route_guide/helper.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_
+#define GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_
+
+#include <string>
+#include <vector>
+
+namespace examples {
+class Feature;
+
+std::string GetDbFileContent(int argc, char** argv);
+
+void ParseDb(const std::string& db, std::vector<Feature>* feature_list);
+
+} // namespace examples
+
+#endif // GRPC_COMMON_CPP_ROUTE_GUIDE_HELPER_H_
+
diff --git a/examples/cpp/route_guide/route_guide_client.cc b/examples/cpp/route_guide/route_guide_client.cc
new file mode 100644
index 0000000000..814def27f3
--- /dev/null
+++ b/examples/cpp/route_guide/route_guide_client.cc
@@ -0,0 +1,252 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <chrono>
+#include <iostream>
+#include <memory>
+#include <random>
+#include <string>
+#include <thread>
+
+#include <grpc/grpc.h>
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
+#include "helper.h"
+#include "route_guide.grpc.pb.h"
+
+using grpc::Channel;
+using grpc::ChannelArguments;
+using grpc::ClientContext;
+using grpc::ClientReader;
+using grpc::ClientReaderWriter;
+using grpc::ClientWriter;
+using grpc::Status;
+using examples::Point;
+using examples::Feature;
+using examples::Rectangle;
+using examples::RouteSummary;
+using examples::RouteNote;
+using examples::RouteGuide;
+
+Point MakePoint(long latitude, long longitude) {
+ Point p;
+ p.set_latitude(latitude);
+ p.set_longitude(longitude);
+ return p;
+}
+
+Feature MakeFeature(const std::string& name,
+ long latitude, long longitude) {
+ Feature f;
+ f.set_name(name);
+ f.mutable_location()->CopyFrom(MakePoint(latitude, longitude));
+ return f;
+}
+
+RouteNote MakeRouteNote(const std::string& message,
+ long latitude, long longitude) {
+ RouteNote n;
+ n.set_message(message);
+ n.mutable_location()->CopyFrom(MakePoint(latitude, longitude));
+ return n;
+}
+
+class RouteGuideClient {
+ public:
+ RouteGuideClient(std::shared_ptr<Channel> channel, const std::string& db)
+ : stub_(RouteGuide::NewStub(channel)) {
+ examples::ParseDb(db, &feature_list_);
+ }
+
+ void GetFeature() {
+ Point point;
+ Feature feature;
+ point = MakePoint(409146138, -746188906);
+ GetOneFeature(point, &feature);
+ point = MakePoint(0, 0);
+ GetOneFeature(point, &feature);
+ }
+
+ void ListFeatures() {
+ examples::Rectangle rect;
+ Feature feature;
+ ClientContext context;
+
+ rect.mutable_lo()->set_latitude(400000000);
+ rect.mutable_lo()->set_longitude(-750000000);
+ rect.mutable_hi()->set_latitude(420000000);
+ rect.mutable_hi()->set_longitude(-730000000);
+ std::cout << "Looking for features between 40, -75 and 42, -73"
+ << std::endl;
+
+ std::unique_ptr<ClientReader<Feature> > reader(
+ stub_->ListFeatures(&context, rect));
+ while (reader->Read(&feature)) {
+ std::cout << "Found feature called "
+ << feature.name() << " at "
+ << feature.location().latitude()/kCoordFactor_ << ", "
+ << feature.location().longitude()/kCoordFactor_ << std::endl;
+ }
+ Status status = reader->Finish();
+ if (status.ok()) {
+ std::cout << "ListFeatures rpc succeeded." << std::endl;
+ } else {
+ std::cout << "ListFeatures rpc failed." << std::endl;
+ }
+ }
+
+ void RecordRoute() {
+ Point point;
+ RouteSummary stats;
+ ClientContext context;
+ const int kPoints = 10;
+ unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
+
+ std::default_random_engine generator(seed);
+ std::uniform_int_distribution<int> feature_distribution(
+ 0, feature_list_.size() - 1);
+ std::uniform_int_distribution<int> delay_distribution(
+ 500, 1500);
+
+ std::unique_ptr<ClientWriter<Point> > writer(
+ stub_->RecordRoute(&context, &stats));
+ for (int i = 0; i < kPoints; i++) {
+ const Feature& f = feature_list_[feature_distribution(generator)];
+ std::cout << "Visiting point "
+ << f.location().latitude()/kCoordFactor_ << ", "
+ << f.location().longitude()/kCoordFactor_ << std::endl;
+ if (!writer->Write(f.location())) {
+ // Broken stream.
+ break;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(
+ delay_distribution(generator)));
+ }
+ writer->WritesDone();
+ Status status = writer->Finish();
+ if (status.ok()) {
+ std::cout << "Finished trip with " << stats.point_count() << " points\n"
+ << "Passed " << stats.feature_count() << " features\n"
+ << "Travelled " << stats.distance() << " meters\n"
+ << "It took " << stats.elapsed_time() << " seconds"
+ << std::endl;
+ } else {
+ std::cout << "RecordRoute rpc failed." << std::endl;
+ }
+ }
+
+ void RouteChat() {
+ ClientContext context;
+
+ std::shared_ptr<ClientReaderWriter<RouteNote, RouteNote> > stream(
+ stub_->RouteChat(&context));
+
+ std::thread writer([stream]() {
+ std::vector<RouteNote> notes{
+ MakeRouteNote("First message", 0, 0),
+ MakeRouteNote("Second message", 0, 1),
+ MakeRouteNote("Third message", 1, 0),
+ MakeRouteNote("Fourth message", 0, 0)};
+ for (const RouteNote& note : notes) {
+ std::cout << "Sending message " << note.message()
+ << " at " << note.location().latitude() << ", "
+ << note.location().longitude() << std::endl;
+ stream->Write(note);
+ }
+ stream->WritesDone();
+ });
+
+ RouteNote server_note;
+ while (stream->Read(&server_note)) {
+ std::cout << "Got message " << server_note.message()
+ << " at " << server_note.location().latitude() << ", "
+ << server_note.location().longitude() << std::endl;
+ }
+ writer.join();
+ Status status = stream->Finish();
+ if (!status.ok()) {
+ std::cout << "RouteChat rpc failed." << std::endl;
+ }
+ }
+
+ private:
+
+ bool GetOneFeature(const Point& point, Feature* feature) {
+ ClientContext context;
+ Status status = stub_->GetFeature(&context, point, feature);
+ if (!status.ok()) {
+ std::cout << "GetFeature rpc failed." << std::endl;
+ return false;
+ }
+ if (!feature->has_location()) {
+ std::cout << "Server returns incomplete feature." << std::endl;
+ return false;
+ }
+ if (feature->name().empty()) {
+ std::cout << "Found no feature at "
+ << feature->location().latitude()/kCoordFactor_ << ", "
+ << feature->location().longitude()/kCoordFactor_ << std::endl;
+ } else {
+ std::cout << "Found feature called " << feature->name() << " at "
+ << feature->location().latitude()/kCoordFactor_ << ", "
+ << feature->location().longitude()/kCoordFactor_ << std::endl;
+ }
+ return true;
+ }
+
+ const float kCoordFactor_ = 10000000.0;
+ std::unique_ptr<RouteGuide::Stub> stub_;
+ std::vector<Feature> feature_list_;
+};
+
+int main(int argc, char** argv) {
+ // Expect only arg: --db_path=path/to/route_guide_db.json.
+ std::string db = examples::GetDbFileContent(argc, argv);
+ RouteGuideClient guide(
+ grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(),
+ ChannelArguments()),
+ db);
+
+ std::cout << "-------------- GetFeature --------------" << std::endl;
+ guide.GetFeature();
+ std::cout << "-------------- ListFeatures --------------" << std::endl;
+ guide.ListFeatures();
+ std::cout << "-------------- RecordRoute --------------" << std::endl;
+ guide.RecordRoute();
+ std::cout << "-------------- RouteChat --------------" << std::endl;
+ guide.RouteChat();
+
+ return 0;
+}
diff --git a/examples/cpp/route_guide/route_guide_db.json b/examples/cpp/route_guide/route_guide_db.json
new file mode 100644
index 0000000000..9d6a980ab7
--- /dev/null
+++ b/examples/cpp/route_guide/route_guide_db.json
@@ -0,0 +1,601 @@
+[{
+ "location": {
+ "latitude": 407838351,
+ "longitude": -746143763
+ },
+ "name": "Patriots Path, Mendham, NJ 07945, USA"
+}, {
+ "location": {
+ "latitude": 408122808,
+ "longitude": -743999179
+ },
+ "name": "101 New Jersey 10, Whippany, NJ 07981, USA"
+}, {
+ "location": {
+ "latitude": 413628156,
+ "longitude": -749015468
+ },
+ "name": "U.S. 6, Shohola, PA 18458, USA"
+}, {
+ "location": {
+ "latitude": 419999544,
+ "longitude": -740371136
+ },
+ "name": "5 Conners Road, Kingston, NY 12401, USA"
+}, {
+ "location": {
+ "latitude": 414008389,
+ "longitude": -743951297
+ },
+ "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
+}, {
+ "location": {
+ "latitude": 419611318,
+ "longitude": -746524769
+ },
+ "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
+}, {
+ "location": {
+ "latitude": 406109563,
+ "longitude": -742186778
+ },
+ "name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
+}, {
+ "location": {
+ "latitude": 416802456,
+ "longitude": -742370183
+ },
+ "name": "352 South Mountain Road, Wallkill, NY 12589, USA"
+}, {
+ "location": {
+ "latitude": 412950425,
+ "longitude": -741077389
+ },
+ "name": "Bailey Turn Road, Harriman, NY 10926, USA"
+}, {
+ "location": {
+ "latitude": 412144655,
+ "longitude": -743949739
+ },
+ "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
+}, {
+ "location": {
+ "latitude": 415736605,
+ "longitude": -742847522
+ },
+ "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
+}, {
+ "location": {
+ "latitude": 413843930,
+ "longitude": -740501726
+ },
+ "name": "162 Merrill Road, Highland Mills, NY 10930, USA"
+}, {
+ "location": {
+ "latitude": 410873075,
+ "longitude": -744459023
+ },
+ "name": "Clinton Road, West Milford, NJ 07480, USA"
+}, {
+ "location": {
+ "latitude": 412346009,
+ "longitude": -744026814
+ },
+ "name": "16 Old Brook Lane, Warwick, NY 10990, USA"
+}, {
+ "location": {
+ "latitude": 402948455,
+ "longitude": -747903913
+ },
+ "name": "3 Drake Lane, Pennington, NJ 08534, USA"
+}, {
+ "location": {
+ "latitude": 406337092,
+ "longitude": -740122226
+ },
+ "name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
+}, {
+ "location": {
+ "latitude": 406421967,
+ "longitude": -747727624
+ },
+ "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
+}, {
+ "location": {
+ "latitude": 416318082,
+ "longitude": -749677716
+ },
+ "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
+}, {
+ "location": {
+ "latitude": 415301720,
+ "longitude": -748416257
+ },
+ "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
+}, {
+ "location": {
+ "latitude": 402647019,
+ "longitude": -747071791
+ },
+ "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
+}, {
+ "location": {
+ "latitude": 412567807,
+ "longitude": -741058078
+ },
+ "name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
+}, {
+ "location": {
+ "latitude": 416855156,
+ "longitude": -744420597
+ },
+ "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
+}, {
+ "location": {
+ "latitude": 404663628,
+ "longitude": -744820157
+ },
+ "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
+}, {
+ "location": {
+ "latitude": 407113723,
+ "longitude": -749746483
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 402133926,
+ "longitude": -743613249
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 400273442,
+ "longitude": -741220915
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 411236786,
+ "longitude": -744070769
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 411633782,
+ "longitude": -746784970
+ },
+ "name": "211-225 Plains Road, Augusta, NJ 07822, USA"
+}, {
+ "location": {
+ "latitude": 415830701,
+ "longitude": -742952812
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 413447164,
+ "longitude": -748712898
+ },
+ "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
+}, {
+ "location": {
+ "latitude": 405047245,
+ "longitude": -749800722
+ },
+ "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
+}, {
+ "location": {
+ "latitude": 418858923,
+ "longitude": -746156790
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 417951888,
+ "longitude": -748484944
+ },
+ "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
+}, {
+ "location": {
+ "latitude": 407033786,
+ "longitude": -743977337
+ },
+ "name": "26 East 3rd Street, New Providence, NJ 07974, USA"
+}, {
+ "location": {
+ "latitude": 417548014,
+ "longitude": -740075041
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 410395868,
+ "longitude": -744972325
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 404615353,
+ "longitude": -745129803
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 406589790,
+ "longitude": -743560121
+ },
+ "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
+}, {
+ "location": {
+ "latitude": 414653148,
+ "longitude": -740477477
+ },
+ "name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
+}, {
+ "location": {
+ "latitude": 405957808,
+ "longitude": -743255336
+ },
+ "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
+}, {
+ "location": {
+ "latitude": 411733589,
+ "longitude": -741648093
+ },
+ "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
+}, {
+ "location": {
+ "latitude": 412676291,
+ "longitude": -742606606
+ },
+ "name": "1270 Lakes Road, Monroe, NY 10950, USA"
+}, {
+ "location": {
+ "latitude": 409224445,
+ "longitude": -748286738
+ },
+ "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
+}, {
+ "location": {
+ "latitude": 406523420,
+ "longitude": -742135517
+ },
+ "name": "652 Garden Street, Elizabeth, NJ 07202, USA"
+}, {
+ "location": {
+ "latitude": 401827388,
+ "longitude": -740294537
+ },
+ "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
+}, {
+ "location": {
+ "latitude": 410564152,
+ "longitude": -743685054
+ },
+ "name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
+}, {
+ "location": {
+ "latitude": 408472324,
+ "longitude": -740726046
+ },
+ "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
+}, {
+ "location": {
+ "latitude": 412452168,
+ "longitude": -740214052
+ },
+ "name": "5 White Oak Lane, Stony Point, NY 10980, USA"
+}, {
+ "location": {
+ "latitude": 409146138,
+ "longitude": -746188906
+ },
+ "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
+}, {
+ "location": {
+ "latitude": 404701380,
+ "longitude": -744781745
+ },
+ "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
+}, {
+ "location": {
+ "latitude": 409642566,
+ "longitude": -746017679
+ },
+ "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
+}, {
+ "location": {
+ "latitude": 408031728,
+ "longitude": -748645385
+ },
+ "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
+}, {
+ "location": {
+ "latitude": 413700272,
+ "longitude": -742135189
+ },
+ "name": "367 Prospect Road, Chester, NY 10918, USA"
+}, {
+ "location": {
+ "latitude": 404310607,
+ "longitude": -740282632
+ },
+ "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
+}, {
+ "location": {
+ "latitude": 409319800,
+ "longitude": -746201391
+ },
+ "name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
+}, {
+ "location": {
+ "latitude": 406685311,
+ "longitude": -742108603
+ },
+ "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
+}, {
+ "location": {
+ "latitude": 419018117,
+ "longitude": -749142781
+ },
+ "name": "43 Dreher Road, Roscoe, NY 12776, USA"
+}, {
+ "location": {
+ "latitude": 412856162,
+ "longitude": -745148837
+ },
+ "name": "Swan Street, Pine Island, NY 10969, USA"
+}, {
+ "location": {
+ "latitude": 416560744,
+ "longitude": -746721964
+ },
+ "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
+}, {
+ "location": {
+ "latitude": 405314270,
+ "longitude": -749836354
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 414219548,
+ "longitude": -743327440
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 415534177,
+ "longitude": -742900616
+ },
+ "name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
+}, {
+ "location": {
+ "latitude": 406898530,
+ "longitude": -749127080
+ },
+ "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
+}, {
+ "location": {
+ "latitude": 407586880,
+ "longitude": -741670168
+ },
+ "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
+}, {
+ "location": {
+ "latitude": 400106455,
+ "longitude": -742870190
+ },
+ "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
+}, {
+ "location": {
+ "latitude": 400066188,
+ "longitude": -746793294
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 418803880,
+ "longitude": -744102673
+ },
+ "name": "40 Mountain Road, Napanoch, NY 12458, USA"
+}, {
+ "location": {
+ "latitude": 414204288,
+ "longitude": -747895140
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 414777405,
+ "longitude": -740615601
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 415464475,
+ "longitude": -747175374
+ },
+ "name": "48 North Road, Forestburgh, NY 12777, USA"
+}, {
+ "location": {
+ "latitude": 404062378,
+ "longitude": -746376177
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 405688272,
+ "longitude": -749285130
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 400342070,
+ "longitude": -748788996
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 401809022,
+ "longitude": -744157964
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 404226644,
+ "longitude": -740517141
+ },
+ "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
+}, {
+ "location": {
+ "latitude": 410322033,
+ "longitude": -747871659
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 407100674,
+ "longitude": -747742727
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 418811433,
+ "longitude": -741718005
+ },
+ "name": "213 Bush Road, Stone Ridge, NY 12484, USA"
+}, {
+ "location": {
+ "latitude": 415034302,
+ "longitude": -743850945
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 411349992,
+ "longitude": -743694161
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 404839914,
+ "longitude": -744759616
+ },
+ "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
+}, {
+ "location": {
+ "latitude": 414638017,
+ "longitude": -745957854
+ },
+ "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
+}, {
+ "location": {
+ "latitude": 412127800,
+ "longitude": -740173578
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 401263460,
+ "longitude": -747964303
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 412843391,
+ "longitude": -749086026
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 418512773,
+ "longitude": -743067823
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 404318328,
+ "longitude": -740835638
+ },
+ "name": "42-102 Main Street, Belford, NJ 07718, USA"
+}, {
+ "location": {
+ "latitude": 419020746,
+ "longitude": -741172328
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 404080723,
+ "longitude": -746119569
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 401012643,
+ "longitude": -744035134
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 404306372,
+ "longitude": -741079661
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 403966326,
+ "longitude": -748519297
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 405002031,
+ "longitude": -748407866
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 409532885,
+ "longitude": -742200683
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 416851321,
+ "longitude": -742674555
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 406411633,
+ "longitude": -741722051
+ },
+ "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
+}, {
+ "location": {
+ "latitude": 413069058,
+ "longitude": -744597778
+ },
+ "name": "261 Van Sickle Road, Goshen, NY 10924, USA"
+}, {
+ "location": {
+ "latitude": 418465462,
+ "longitude": -746859398
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 411733222,
+ "longitude": -744228360
+ },
+ "name": ""
+}, {
+ "location": {
+ "latitude": 410248224,
+ "longitude": -747127767
+ },
+ "name": "3 Hasta Way, Newton, NJ 07860, USA"
+}]
diff --git a/examples/cpp/route_guide/route_guide_server.cc b/examples/cpp/route_guide/route_guide_server.cc
new file mode 100644
index 0000000000..b37539299a
--- /dev/null
+++ b/examples/cpp/route_guide/route_guide_server.cc
@@ -0,0 +1,202 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <algorithm>
+#include <chrono>
+#include <cmath>
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <grpc/grpc.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
+#include "helper.h"
+#include "route_guide.grpc.pb.h"
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::ServerReader;
+using grpc::ServerReaderWriter;
+using grpc::ServerWriter;
+using grpc::Status;
+using examples::Point;
+using examples::Feature;
+using examples::Rectangle;
+using examples::RouteSummary;
+using examples::RouteNote;
+using examples::RouteGuide;
+using std::chrono::system_clock;
+
+
+float ConvertToRadians(float num) {
+ return num * 3.1415926 /180;
+}
+
+float GetDistance(const Point& start, const Point& end) {
+ const float kCoordFactor = 10000000.0;
+ float lat_1 = start.latitude() / kCoordFactor;
+ float lat_2 = end.latitude() / kCoordFactor;
+ float lon_1 = start.longitude() / kCoordFactor;
+ float lon_2 = end.longitude() / kCoordFactor;
+ float lat_rad_1 = ConvertToRadians(lat_1);
+ float lat_rad_2 = ConvertToRadians(lat_2);
+ float delta_lat_rad = ConvertToRadians(lat_2-lat_1);
+ float delta_lon_rad = ConvertToRadians(lon_2-lon_1);
+
+ float a = pow(sin(delta_lat_rad/2), 2) + cos(lat_rad_1) * cos(lat_rad_2) *
+ pow(sin(delta_lon_rad/2), 2);
+ float c = 2 * atan2(sqrt(a), sqrt(1-a));
+ int R = 6371000; // metres
+
+ return R * c;
+}
+
+std::string GetFeatureName(const Point& point,
+ const std::vector<Feature>& feature_list) {
+ for (const Feature& f : feature_list) {
+ if (f.location().latitude() == point.latitude() &&
+ f.location().longitude() == point.longitude()) {
+ return f.name();
+ }
+ }
+ return "";
+}
+
+class RouteGuideImpl final : public RouteGuide::Service {
+ public:
+ explicit RouteGuideImpl(const std::string& db) {
+ examples::ParseDb(db, &feature_list_);
+ }
+
+ Status GetFeature(ServerContext* context, const Point* point,
+ Feature* feature) override {
+ feature->set_name(GetFeatureName(*point, feature_list_));
+ feature->mutable_location()->CopyFrom(*point);
+ return Status::OK;
+ }
+
+ Status ListFeatures(ServerContext* context,
+ const examples::Rectangle* rectangle,
+ ServerWriter<Feature>* writer) override {
+ auto lo = rectangle->lo();
+ auto hi = rectangle->hi();
+ long left = (std::min)(lo.longitude(), hi.longitude());
+ long right = (std::max)(lo.longitude(), hi.longitude());
+ long top = (std::max)(lo.latitude(), hi.latitude());
+ long bottom = (std::min)(lo.latitude(), hi.latitude());
+ for (const Feature& f : feature_list_) {
+ if (f.location().longitude() >= left &&
+ f.location().longitude() <= right &&
+ f.location().latitude() >= bottom &&
+ f.location().latitude() <= top) {
+ writer->Write(f);
+ }
+ }
+ return Status::OK;
+ }
+
+ Status RecordRoute(ServerContext* context, ServerReader<Point>* reader,
+ RouteSummary* summary) override {
+ Point point;
+ int point_count = 0;
+ int feature_count = 0;
+ float distance = 0.0;
+ Point previous;
+
+ system_clock::time_point start_time = system_clock::now();
+ while (reader->Read(&point)) {
+ point_count++;
+ if (!GetFeatureName(point, feature_list_).empty()) {
+ feature_count++;
+ }
+ if (point_count != 1) {
+ distance += GetDistance(previous, point);
+ }
+ previous = point;
+ }
+ system_clock::time_point end_time = system_clock::now();
+ summary->set_point_count(point_count);
+ summary->set_feature_count(feature_count);
+ summary->set_distance(static_cast<long>(distance));
+ auto secs = std::chrono::duration_cast<std::chrono::seconds>(
+ end_time - start_time);
+ summary->set_elapsed_time(secs.count());
+
+ return Status::OK;
+ }
+
+ Status RouteChat(ServerContext* context,
+ ServerReaderWriter<RouteNote, RouteNote>* stream) override {
+ std::vector<RouteNote> received_notes;
+ RouteNote note;
+ while (stream->Read(&note)) {
+ for (const RouteNote& n : received_notes) {
+ if (n.location().latitude() == note.location().latitude() &&
+ n.location().longitude() == note.location().longitude()) {
+ stream->Write(n);
+ }
+ }
+ received_notes.push_back(note);
+ }
+
+ return Status::OK;
+ }
+
+ private:
+
+ std::vector<Feature> feature_list_;
+};
+
+void RunServer(const std::string& db_path) {
+ std::string server_address("0.0.0.0:50051");
+ RouteGuideImpl service(db_path);
+
+ ServerBuilder builder;
+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ builder.RegisterService(&service);
+ std::unique_ptr<Server> server(builder.BuildAndStart());
+ std::cout << "Server listening on " << server_address << std::endl;
+ server->Wait();
+}
+
+int main(int argc, char** argv) {
+ // Expect only arg: --db_path=path/to/route_guide_db.json.
+ std::string db = examples::GetDbFileContent(argc, argv);
+ RunServer(db);
+
+ return 0;
+}