mirror of https://github.com/grpc/grpc.git
Merge pull request #40 from yang-g/route
Add a dummy implementation of route_guide in c++.pull/3109/head
commit
1efae2547a
6 changed files with 1407 additions and 0 deletions
@ -0,0 +1,110 @@ |
||||
#
|
||||
# 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 -lgpr -lgrpc -lgrpc++ -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_client.o helper.o |
||||
$(CXX) $^ $(LDFLAGS) -o $@
|
||||
|
||||
route_guide_server: route_guide.pb.o route_guide_server.o helper.o |
||||
$(CXX) $^ $(LDFLAGS) -o $@
|
||||
|
||||
%.pb.cc: %.proto |
||||
$(PROTOC) -I $(PROTOS_PATH) --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
|
||||
|
||||
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 |
@ -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.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
|
||||
|
@ -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_
|
||||
|
@ -0,0 +1,260 @@ |
||||
/*
|
||||
* |
||||
* 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_arguments.h> |
||||
#include <grpc++/channel_interface.h> |
||||
#include <grpc++/client_context.h> |
||||
#include <grpc++/create_channel.h> |
||||
#include <grpc++/status.h> |
||||
#include <grpc++/stream.h> |
||||
#include "helper.h" |
||||
#include "route_guide.pb.h" |
||||
|
||||
using grpc::ChannelArguments; |
||||
using grpc::ChannelInterface; |
||||
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<ChannelInterface> 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() { |
||||
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().latitude()/kCoordFactor_ << std::endl; |
||||
} |
||||
Status status = reader->Finish(); |
||||
if (status.IsOk()) { |
||||
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.IsOk()) { |
||||
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.IsOk()) { |
||||
std::cout << "RouteChat rpc failed." << std::endl; |
||||
} |
||||
} |
||||
|
||||
void Shutdown() { stub_.reset(); } |
||||
|
||||
private: |
||||
|
||||
bool GetOneFeature(const Point& point, Feature* feature) { |
||||
ClientContext context; |
||||
Status status = stub_->GetFeature(&context, point, feature); |
||||
if (!status.IsOk()) { |
||||
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) { |
||||
grpc_init(); |
||||
|
||||
// Expect only arg: --db_path=path/to/route_guide_db.json.
|
||||
std::string db = examples::GetDbFileContent(argc, argv); |
||||
RouteGuideClient guide( |
||||
grpc::CreateChannelDeprecated("localhost:50051", 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(); |
||||
|
||||
guide.Shutdown(); |
||||
|
||||
grpc_shutdown(); |
||||
} |
@ -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" |
||||
}] |
@ -0,0 +1,208 @@ |
||||
/*
|
||||
* |
||||
* 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 <thread> |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <grpc++/server.h> |
||||
#include <grpc++/server_builder.h> |
||||
#include <grpc++/server_context.h> |
||||
#include <grpc++/status.h> |
||||
#include <grpc++/stream.h> |
||||
#include "helper.h" |
||||
#include "route_guide.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 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(¬e)) { |
||||
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.AddPort(server_address); |
||||
builder.RegisterService(&service); |
||||
std::unique_ptr<Server> server(builder.BuildAndStart()); |
||||
std::cout << "Server listening on " << server_address << std::endl; |
||||
while (true) { |
||||
std::this_thread::sleep_for(std::chrono::seconds(5)); |
||||
} |
||||
} |
||||
|
||||
int main(int argc, char** argv) { |
||||
grpc_init(); |
||||
|
||||
// Expect only arg: --db_path=path/to/route_guide_db.json.
|
||||
std::string db = examples::GetDbFileContent(argc, argv); |
||||
RunServer(db); |
||||
|
||||
grpc_shutdown(); |
||||
return 0; |
||||
} |
Loading…
Reference in new issue