aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/cpp/helloworld
diff options
context:
space:
mode:
authorGravatar murgatroid99 <mlumish@google.com>2015-08-28 12:36:48 -0700
committerGravatar murgatroid99 <mlumish@google.com>2015-08-28 12:36:48 -0700
commit970842535d6abdaf6c5c040fb2b432c423200f26 (patch)
treefac649e584b56da9bff6c19e8d3a637ce55505a4 /examples/cpp/helloworld
parent4e53265f6470a8736967f9cbc2e0797ad04755ca (diff)
parent956e411e31c97836702aac5675e9f509b2231426 (diff)
Merge branch 'master' into node_method_name_conflicts
Diffstat (limited to 'examples/cpp/helloworld')
-rw-r--r--examples/cpp/helloworld/Makefile119
-rw-r--r--examples/cpp/helloworld/README.md260
-rw-r--r--examples/cpp/helloworld/greeter_async_client.cc98
-rw-r--r--examples/cpp/helloworld/greeter_async_server.cc136
-rw-r--r--examples/cpp/helloworld/greeter_client.cc85
-rw-r--r--examples/cpp/helloworld/greeter_server.cc78
6 files changed, 776 insertions, 0 deletions
diff --git a/examples/cpp/helloworld/Makefile b/examples/cpp/helloworld/Makefile
new file mode 100644
index 0000000000..f2093afa05
--- /dev/null
+++ b/examples/cpp/helloworld/Makefile
@@ -0,0 +1,119 @@
+#
+# 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 greeter_client greeter_server greeter_async_client greeter_async_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 $@
+
+greeter_async_client: helloworld.pb.o helloworld.grpc.pb.o greeter_async_client.o
+ $(CXX) $^ $(LDFLAGS) -o $@
+
+greeter_async_server: helloworld.pb.o helloworld.grpc.pb.o greeter_async_server.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 greeter_client greeter_server greeter_async_client greeter_async_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/helloworld/README.md b/examples/cpp/helloworld/README.md
new file mode 100644
index 0000000000..641aadd52d
--- /dev/null
+++ b/examples/cpp/helloworld/README.md
@@ -0,0 +1,260 @@
+# gRPC C++ Hello World Tutorial
+
+### Install gRPC
+Make sure you have installed gRPC on your system. Follow the instructions here:
+[https://github.com/grpc/grpc/blob/master/INSTALL](https://github.com/grpc/grpc/blob/master/INSTALL).
+
+### 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 https://github.com/grpc/grpc.git
+```
+
+Change your current directory to examples/cpp/helloworld
+
+```sh
+$ cd examples/cpp/helloworld/
+```
+
+### Defining a service
+
+The first step in creating our example is to define a *service*: an RPC
+service specifies the methods that can be called remotely with their parameters
+and return types. As you saw in the
+[overview](#protocolbuffers) above, gRPC does this using [protocol
+buffers](https://developers.google.com/protocol-buffers/docs/overview). We
+use the protocol buffers interface definition language (IDL) to define our
+service methods, and define the parameters and return
+types as protocol buffer message types. Both the client and the
+server use interface code generated from the service definition.
+
+Here's our example service definition, defined using protocol buffers IDL in
+[helloworld.proto](examples/protos/helloworld.proto). The `Greeting`
+service has one method, `hello`, that lets the server receive a single
+`HelloRequest`
+message from the remote client containing the user's name, then send back
+a greeting in a single `HelloReply`. This is the simplest type of RPC you
+can specify in gRPC - we'll look at some other types later in this document.
+
+```
+syntax = "proto3";
+
+option java_package = "ex.grpc";
+
+package helloworld;
+
+// The greeting service definition.
+service Greeter {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (HelloReply) {}
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+ string message = 1;
+}
+
+```
+
+<a name="generating"></a>
+### Generating gRPC code
+
+Once we've defined our service, we use the protocol buffer compiler
+`protoc` to generate the special client and server code we need to create
+our application. The generated code contains both stub code for clients to
+use and an abstract interface for servers to implement, both with the method
+defined in our `Greeting` service.
+
+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
+
+- Create a channel. A channel is a logical connection to an endpoint. A gRPC
+ channel can be created with the target address, credentials to use and
+ arguments as follows
+
+ ```
+ auto channel = CreateChannel("localhost:50051", InsecureCredentials(), ChannelArguments());
+ ```
+
+- Create a stub. A stub implements the rpc methods of a service and in the
+ generated code, a method is provided to created a stub with a channel:
+
+ ```
+ auto stub = helloworld::Greeter::NewStub(channel);
+ ```
+
+- Make a unary rpc, with `ClientContext` and request/response proto messages.
+
+ ```
+ ClientContext context;
+ HelloRequest request;
+ request.set_name("hello");
+ HelloReply reply;
+ Status status = stub->SayHello(&context, request, &reply);
+ ```
+
+- Check returned status and response.
+
+ ```
+ if (status.ok()) {
+ // check reply.message()
+ } else {
+ // rpc failed.
+ }
+ ```
+
+For a working example, refer to [greeter_client.cc](examples/cpp/helloworld/greeter_client.cc).
+
+### Writing a server
+
+- Implement the service interface
+
+ ```
+ class GreeterServiceImpl final : public Greeter::Service {
+ Status SayHello(ServerContext* context, const HelloRequest* request,
+ HelloReply* reply) override {
+ std::string prefix("Hello ");
+ reply->set_message(prefix + request->name());
+ return Status::OK;
+ }
+ };
+
+ ```
+
+- Build a server exporting the service
+
+ ```
+ GreeterServiceImpl service;
+ ServerBuilder builder;
+ builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials());
+ builder.RegisterService(&service);
+ std::unique_ptr<Server> server(builder.BuildAndStart());
+ ```
+
+For a working example, refer to [greeter_server.cc](examples/cpp/helloworld/greeter_server.cc).
+
+### Writing asynchronous client and server
+
+gRPC uses `CompletionQueue` API for asynchronous operations. The basic work flow
+is
+- bind a `CompletionQueue` to a rpc call
+- do something like a read or write, present with a unique `void*` tag
+- call `CompletionQueue::Next` to wait for operations to complete. If a tag
+ appears, it indicates that the corresponding operation is complete.
+
+#### Async client
+
+The channel and stub creation code is the same as the sync client.
+
+- Initiate the rpc and create a handle for the rpc. Bind the rpc to a
+ `CompletionQueue`.
+
+ ```
+ CompletionQueue cq;
+ auto rpc = stub->AsyncSayHello(&context, request, &cq);
+ ```
+
+- Ask for reply and final status, with a unique tag
+
+ ```
+ Status status;
+ rpc->Finish(&reply, &status, (void*)1);
+ ```
+
+- Wait for the completion queue to return the next tag. The reply and status are
+ ready once the tag passed into the corresponding `Finish()` call is returned.
+
+ ```
+ void* got_tag;
+ bool ok = false;
+ cq.Next(&got_tag, &ok);
+ if (ok && got_tag == (void*)1) {
+ // check reply and status
+ }
+ ```
+
+For a working example, refer to [greeter_async_client.cc](examples/cpp/helloworld/greeter_async_client.cc).
+
+#### Async server
+
+The server implementation requests a rpc call with a tag and then wait for the
+completion queue to return the tag. The basic flow is
+
+- Build a server exporting the async service
+
+ ```
+ helloworld::Greeter::AsyncService service;
+ ServerBuilder builder;
+ builder.AddListeningPort("0.0.0.0:50051", InsecureServerCredentials());
+ builder.RegisterAsyncService(&service);
+ auto cq = builder.AddCompletionQueue();
+ auto server = builder.BuildAndStart();
+ ```
+
+- Request one rpc
+
+ ```
+ ServerContext context;
+ HelloRequest request;
+ ServerAsyncResponseWriter<HelloReply> responder;
+ service.RequestSayHello(&context, &request, &responder, &cq, &cq, (void*)1);
+ ```
+
+- Wait for the completion queue to return the tag. The context, request and
+ responder are ready once the tag is retrieved.
+
+ ```
+ HelloReply reply;
+ Status status;
+ void* got_tag;
+ bool ok = false;
+ cq.Next(&got_tag, &ok);
+ if (ok && got_tag == (void*)1) {
+ // set reply and status
+ responder.Finish(reply, status, (void*)2);
+ }
+ ```
+
+- Wait for the completion queue to return the tag. The rpc is finished when the
+ tag is back.
+
+ ```
+ void* got_tag;
+ bool ok = false;
+ cq.Next(&got_tag, &ok);
+ if (ok && got_tag == (void*)2) {
+ // clean up
+ }
+ ```
+
+To handle multiple rpcs, the async server creates an object `CallData` to
+maintain the state of each rpc and use the address of it as the unique tag. For
+simplicity the server only uses one completion queue for all events, and runs a
+main loop in `HandleRpcs` to query the queue.
+
+For a working example, refer to [greeter_async_server.cc](examples/cpp/helloworld/greeter_async_server.cc).
+
+
+
+
diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc
new file mode 100644
index 0000000000..d99f89b135
--- /dev/null
+++ b/examples/cpp/helloworld/greeter_async_client.cc
@@ -0,0 +1,98 @@
+/*
+ *
+ * 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 <iostream>
+#include <memory>
+#include <string>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/completion_queue.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
+#include "helloworld.grpc.pb.h"
+
+using grpc::Channel;
+using grpc::ChannelArguments;
+using grpc::ClientAsyncResponseReader;
+using grpc::ClientContext;
+using grpc::CompletionQueue;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+class GreeterClient {
+ public:
+ explicit GreeterClient(std::shared_ptr<Channel> channel)
+ : stub_(Greeter::NewStub(channel)) {}
+
+ std::string SayHello(const std::string& user) {
+ HelloRequest request;
+ request.set_name(user);
+ HelloReply reply;
+ ClientContext context;
+ CompletionQueue cq;
+ Status status;
+
+ std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
+ stub_->AsyncSayHello(&context, request, &cq));
+ rpc->Finish(&reply, &status, (void*)1);
+ void* got_tag;
+ bool ok = false;
+ cq.Next(&got_tag, &ok);
+ GPR_ASSERT(ok);
+ GPR_ASSERT(got_tag == (void*)1);
+
+ if (status.ok()) {
+ return reply.message();
+ } else {
+ return "Rpc failed";
+ }
+ }
+
+ private:
+ std::unique_ptr<Greeter::Stub> stub_;
+};
+
+int main(int argc, char** argv) {
+ GreeterClient greeter(grpc::CreateChannel(
+ "localhost:50051", grpc::InsecureCredentials(), ChannelArguments()));
+ std::string user("world");
+ std::string reply = greeter.SayHello(user);
+ std::cout << "Greeter received: " << reply << std::endl;
+
+ return 0;
+}
diff --git a/examples/cpp/helloworld/greeter_async_server.cc b/examples/cpp/helloworld/greeter_async_server.cc
new file mode 100644
index 0000000000..b8a0dbf0e2
--- /dev/null
+++ b/examples/cpp/helloworld/greeter_async_server.cc
@@ -0,0 +1,136 @@
+/*
+ *
+ * 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 <memory>
+#include <iostream>
+#include <string>
+#include <thread>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc++/completion_queue.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
+#include "helloworld.grpc.pb.h"
+
+using grpc::Server;
+using grpc::ServerAsyncResponseWriter;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::ServerCompletionQueue;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+class ServerImpl final {
+ public:
+ ~ServerImpl() {
+ server_->Shutdown();
+ cq_->Shutdown();
+ }
+
+ // There is no shutdown handling in this code.
+ void Run() {
+ std::string server_address("0.0.0.0:50051");
+
+ ServerBuilder builder;
+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ builder.RegisterAsyncService(&service_);
+ cq_ = builder.AddCompletionQueue();
+ server_ = builder.BuildAndStart();
+ std::cout << "Server listening on " << server_address << std::endl;
+
+ HandleRpcs();
+ }
+
+ private:
+ class CallData {
+ public:
+ CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq)
+ : service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) {
+ Proceed();
+ }
+
+ void Proceed() {
+ if (status_ == CREATE) {
+ service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,
+ this);
+ status_ = PROCESS;
+ } else if (status_ == PROCESS) {
+ new CallData(service_, cq_);
+ std::string prefix("Hello ");
+ reply_.set_message(prefix + request_.name());
+ responder_.Finish(reply_, Status::OK, this);
+ status_ = FINISH;
+ } else {
+ delete this;
+ }
+ }
+
+ private:
+ Greeter::AsyncService* service_;
+ ServerCompletionQueue* cq_;
+ ServerContext ctx_;
+ HelloRequest request_;
+ HelloReply reply_;
+ ServerAsyncResponseWriter<HelloReply> responder_;
+ enum CallStatus { CREATE, PROCESS, FINISH };
+ CallStatus status_;
+ };
+
+ // This can be run in multiple threads if needed.
+ void HandleRpcs() {
+ new CallData(&service_, cq_.get());
+ void* tag;
+ bool ok;
+ while (true) {
+ cq_->Next(&tag, &ok);
+ GPR_ASSERT(ok);
+ static_cast<CallData*>(tag)->Proceed();
+ }
+ }
+
+ std::unique_ptr<ServerCompletionQueue> cq_;
+ Greeter::AsyncService service_;
+ std::unique_ptr<Server> server_;
+};
+
+int main(int argc, char** argv) {
+ ServerImpl server;
+ server.Run();
+
+ return 0;
+}
diff --git a/examples/cpp/helloworld/greeter_client.cc b/examples/cpp/helloworld/greeter_client.cc
new file mode 100644
index 0000000000..dd0358ac95
--- /dev/null
+++ b/examples/cpp/helloworld/greeter_client.cc
@@ -0,0 +1,85 @@
+/*
+ *
+ * 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 <iostream>
+#include <memory>
+#include <string>
+
+#include <grpc/grpc.h>
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
+#include "helloworld.grpc.pb.h"
+
+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)) {}
+
+ std::string SayHello(const std::string& user) {
+ HelloRequest request;
+ request.set_name(user);
+ HelloReply reply;
+ ClientContext context;
+
+ Status status = stub_->SayHello(&context, request, &reply);
+ if (status.ok()) {
+ return reply.message();
+ } else {
+ return "Rpc failed";
+ }
+ }
+
+ private:
+ std::unique_ptr<Greeter::Stub> stub_;
+};
+
+int main(int argc, char** argv) {
+ GreeterClient greeter(
+ grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(),
+ ChannelArguments()));
+ std::string user("world");
+ std::string reply = greeter.SayHello(user);
+ std::cout << "Greeter received: " << reply << std::endl;
+
+ return 0;
+}
diff --git a/examples/cpp/helloworld/greeter_server.cc b/examples/cpp/helloworld/greeter_server.cc
new file mode 100644
index 0000000000..c1efdf563c
--- /dev/null
+++ b/examples/cpp/helloworld/greeter_server.cc
@@ -0,0 +1,78 @@
+/*
+ *
+ * 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 <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 "helloworld.grpc.pb.h"
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+class GreeterServiceImpl final : public Greeter::Service {
+ Status SayHello(ServerContext* context, const HelloRequest* request,
+ HelloReply* reply) override {
+ 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;
+ 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) {
+ RunServer();
+
+ return 0;
+}