aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples
diff options
context:
space:
mode:
authorGravatar Juanli Shen <juanlishen@google.com>2018-12-12 15:06:12 -0800
committerGravatar Juanli Shen <juanlishen@google.com>2018-12-12 15:06:12 -0800
commita69fa16dfdb7795f4918c50f607c4306e598d4d9 (patch)
tree2240feac57ea03b5dcc7e45bb1f355994536db4a /examples
parent01afcb4feeae09e6db22bcc54112a1e10d61c8ac (diff)
Add compression example
Diffstat (limited to 'examples')
-rw-r--r--examples/cpp/compression/Makefile110
-rw-r--r--examples/cpp/compression/README.md84
-rw-r--r--examples/cpp/compression/greeter_client.cc93
-rw-r--r--examples/cpp/compression/greeter_server.cc76
4 files changed, 363 insertions, 0 deletions
diff --git a/examples/cpp/compression/Makefile b/examples/cpp/compression/Makefile
new file mode 100644
index 0000000000..47211886ff
--- /dev/null
+++ b/examples/cpp/compression/Makefile
@@ -0,0 +1,110 @@
+#
+# 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.
+#
+
+HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
+SYSTEM ?= $(HOST_SYSTEM)
+CXX = g++
+CPPFLAGS += `pkg-config --cflags protobuf grpc`
+CXXFLAGS += -std=c++11
+ifeq ($(SYSTEM),Darwin)
+LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
+ -lgrpc++_reflection\
+ -ldl
+else
+LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
+ -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
+ -ldl
+endif
+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 greeter_client greeter_server
+
+greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o
+ $(CXX) $^ $(LDFLAGS) -o $@
+
+greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o
+ $(CXX) $^ $(LDFLAGS) -o $@
+
+.PRECIOUS: %.grpc.pb.cc
+%.grpc.pb.cc: %.proto
+ $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
+
+.PRECIOUS: %.pb.cc
+%.pb.cc: %.proto
+ $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<
+
+clean:
+ rm -f *.o *.pb.cc *.pb.h greeter_client greeter_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"
+ @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/compression/README.md b/examples/cpp/compression/README.md
new file mode 100644
index 0000000000..13988f2c0c
--- /dev/null
+++ b/examples/cpp/compression/README.md
@@ -0,0 +1,84 @@
+# gRPC C++ Message Compression Tutorial
+
+### Prerequisite
+Make sure you have run the [hello world example](../helloworld) or understood the basics of gRPC. We will not dive into the details that have been discussed in the hello world example.
+
+### Get the tutorial source code
+
+The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command:
+
+
+```sh
+$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
+```
+
+Change your current directory to examples/cpp/compression
+
+```sh
+$ cd examples/cpp/compression/
+```
+
+### Generating gRPC code
+
+To generate the client and server side interfaces:
+
+```sh
+$ make helloworld.grpc.pb.cc helloworld.pb.cc
+```
+Which internally invokes the proto-compiler as:
+
+```sh
+$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto
+$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto
+```
+
+### Writing a client and a server
+
+The client and the server can be based on the hello world example.
+
+Additionally, we can configure the compression settings.
+
+In the client, set the default compression algorithm of the channel via the channel arg.
+
+```cpp
+ ChannelArguments args;
+ // Set the default compression algorithm for the channel.
+ args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP);
+ GreeterClient greeter(grpc::CreateCustomChannel(
+ "localhost:50051", grpc::InsecureChannelCredentials(), args));
+```
+
+Each call's compression configuration can be overwritten by client context.
+
+```cpp
+ // Overwrite the call's compression algorithm to DEFLATE.
+ context.set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
+```
+
+In the server, set the default compression algorithm via the server builder.
+
+```cpp
+ ServerBuilder builder;
+ // Set the default compression algorithm for the server.
+ builder.SetDefaultCompressionAlgorithm(GRPC_COMPRESS_GZIP);
+```
+
+Each call's compression configuration can be overwritten by server context.
+
+```cpp
+ // Overwrite the call's compression algorithm to DEFLATE.
+ context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
+```
+
+For a working example, refer to [greeter_client.cc](greeter_client.cc) and [greeter_server.cc](greeter_server.cc).
+
+Build and run the (compressing) client and the server by the following commands.
+
+```sh
+make
+./greeter_server
+```
+
+```sh
+./greeter_client
+```
diff --git a/examples/cpp/compression/greeter_client.cc b/examples/cpp/compression/greeter_client.cc
new file mode 100644
index 0000000000..a842817464
--- /dev/null
+++ b/examples/cpp/compression/greeter_client.cc
@@ -0,0 +1,93 @@
+/*
+ *
+ * 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 <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+#ifdef BAZEL_BUILD
+#include "examples/protos/helloworld.grpc.pb.h"
+#else
+#include "helloworld.grpc.pb.h"
+#endif
+
+using grpc::Channel;
+using grpc::ChannelArguments;
+using grpc::ClientContext;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+class GreeterClient {
+ public:
+ GreeterClient(std::shared_ptr<Channel> channel)
+ : stub_(Greeter::NewStub(channel)) {}
+
+ // Assembles the client's payload, sends it and presents the response back
+ // from the server.
+ std::string SayHello(const std::string& user) {
+ // Data we are sending to the server.
+ HelloRequest request;
+ request.set_name(user);
+
+ // Container for the data we expect from the server.
+ HelloReply reply;
+
+ // Context for the client. It could be used to convey extra information to
+ // the server and/or tweak certain RPC behaviors.
+ ClientContext context;
+
+ // Overwrite the call's compression algorithm to DEFLATE.
+ context.set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
+
+ // The actual RPC.
+ Status status = stub_->SayHello(&context, request, &reply);
+
+ // Act upon its status.
+ if (status.ok()) {
+ return reply.message();
+ } else {
+ std::cout << status.error_code() << ": " << status.error_message()
+ << std::endl;
+ return "RPC failed";
+ }
+ }
+
+ private:
+ std::unique_ptr<Greeter::Stub> 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()).
+ ChannelArguments args;
+ // Set the default compression algorithm for the channel.
+ args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP);
+ GreeterClient greeter(grpc::CreateCustomChannel(
+ "localhost:50051", grpc::InsecureChannelCredentials(), args));
+ std::string user("world");
+ std::string reply = greeter.SayHello(user);
+ std::cout << "Greeter received: " << reply << std::endl;
+
+ return 0;
+}
diff --git a/examples/cpp/compression/greeter_server.cc b/examples/cpp/compression/greeter_server.cc
new file mode 100644
index 0000000000..7399017afb
--- /dev/null
+++ b/examples/cpp/compression/greeter_server.cc
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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 <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+#ifdef BAZEL_BUILD
+#include "examples/protos/helloworld.grpc.pb.h"
+#else
+#include "helloworld.grpc.pb.h"
+#endif
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+// Logic and data behind the server's behavior.
+class GreeterServiceImpl final : public Greeter::Service {
+ Status SayHello(ServerContext* context, const HelloRequest* request,
+ HelloReply* reply) override {
+ // Overwrite the call's compression algorithm to DEFLATE.
+ context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
+ std::string prefix("Hello ");
+ reply->set_message(prefix + request->name());
+ return Status::OK;
+ }
+};
+
+void RunServer() {
+ std::string server_address("0.0.0.0:50051");
+ GreeterServiceImpl service;
+
+ ServerBuilder builder;
+ // Set the default compression algorithm for the server.
+ builder.SetDefaultCompressionAlgorithm(GRPC_COMPRESS_GZIP);
+ // 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> 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;
+}