From 7a5a9544ef9afb8456e5241741ceb387153bfb38 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 9 Jan 2019 14:56:42 -0800 Subject: Add a naive client server implementation --- examples/BUILD | 14 ++++ examples/cpp/keyvaluestore/caching_interceptor.cc | 0 examples/cpp/keyvaluestore/client.cc | 85 +++++++++++++++++++ examples/cpp/keyvaluestore/server.cc | 99 +++++++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 examples/cpp/keyvaluestore/caching_interceptor.cc create mode 100644 examples/cpp/keyvaluestore/client.cc create mode 100644 examples/cpp/keyvaluestore/server.cc diff --git a/examples/BUILD b/examples/BUILD index b6cb9d48d3..4fee663bd9 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -98,3 +98,17 @@ cc_binary( defines = ["BAZEL_BUILD"], deps = [":helloworld", "//:grpc++"], ) + +cc_binary( + name = "keyvaluestore_client", + srcs = ["cpp/keyvaluestore/client.cc"], + defines = ["BAZEL_BUILD"], + deps = [":keyvaluestore", "//:grpc++"], +) + +cc_binary( + name = "keyvaluestore_server", + srcs = ["cpp/keyvaluestore/server.cc"], + defines = ["BAZEL_BUILD"], + deps = [":keyvaluestore", "//:grpc++"], +) \ No newline at end of file diff --git a/examples/cpp/keyvaluestore/caching_interceptor.cc b/examples/cpp/keyvaluestore/caching_interceptor.cc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc new file mode 100644 index 0000000000..9f5fa37cb1 --- /dev/null +++ b/examples/cpp/keyvaluestore/client.cc @@ -0,0 +1,85 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using keyvaluestore::Request; +using keyvaluestore::Response; +using keyvaluestore::KeyValueStore; + +class KeyValueStoreClient { + public: + KeyValueStoreClient(std::shared_ptr channel) + : stub_(KeyValueStore::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + void GetValues(const std::vector& keys) { + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + auto stream = stub_->GetValues(&context); + for (const auto& key:keys) { + // Data we are sending to the server. + Request request; + request.set_key(key); + stream->Write(request); + + Response response; + stream->Read(&response); + std::cout << key << " : " << response.value() << "\n"; + } + stream->WritesDone(); + Status status = stream->Finish(); + if(!status.ok()) { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + std::cout << "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + KeyValueStoreClient client(grpc::CreateChannel( + "localhost:50051", grpc::InsecureChannelCredentials())); + std::vector keys = {"key1", "key2", "key3", "key4", "key5"}; + client.GetValues(keys); + + return 0; +} diff --git a/examples/cpp/keyvaluestore/server.cc b/examples/cpp/keyvaluestore/server.cc new file mode 100644 index 0000000000..75d30eb1f8 --- /dev/null +++ b/examples/cpp/keyvaluestore/server.cc @@ -0,0 +1,99 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::ServerReaderWriter; +using grpc::Status; +using keyvaluestore::Request; +using keyvaluestore::Response; +using keyvaluestore::KeyValueStore; + +struct kv_pair { + const char* key; + const char* value; +}; + +static const kv_pair kvs_map[] = { + {"key1", "value1"}, + {"key2", "value2"}, + {"key3", "value3"}, + {"key4", "value4"}, + {"key5", "value5"}, +}; + +const char * get_value_from_map(const char* key) { + for(size_t i = 0; i < sizeof(kvs_map) / sizeof(kv_pair); ++i) { + if(strcmp(key, kvs_map[i].key) == 0) { + return kvs_map[i].value; + } + } + return nullptr; +} + +// Logic and data behind the server's behavior. +class KeyValueStoreServiceImpl final : public KeyValueStore::Service { + Status GetValues(ServerContext* context, ServerReaderWriter *stream) override { + Request request; + while(stream->Read(&request)) { + Response response; + response.set_value(get_value_from_map(request.key().c_str())); + stream->Write(response); + } + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + KeyValueStoreServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} -- cgit v1.2.3