aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/cpp/helloworld/greeter_async_server.cc
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/greeter_async_server.cc
parent4e53265f6470a8736967f9cbc2e0797ad04755ca (diff)
parent956e411e31c97836702aac5675e9f509b2231426 (diff)
Merge branch 'master' into node_method_name_conflicts
Diffstat (limited to 'examples/cpp/helloworld/greeter_async_server.cc')
-rw-r--r--examples/cpp/helloworld/greeter_async_server.cc136
1 files changed, 136 insertions, 0 deletions
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;
+}