greeter_async_server.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <iostream>
20 #include <memory>
21 #include <string>
22 #include <thread>
23 
24 #include <grpc/support/log.h>
25 #include <grpcpp/grpcpp.h>
26 
27 #ifdef BAZEL_BUILD
28 #include "examples/protos/helloworld.grpc.pb.h"
29 #else
30 #include "helloworld.grpc.pb.h"
31 #endif
32 
33 using grpc::Server;
38 using grpc::Status;
42 
43 class ServerImpl final {
44  public:
46  server_->Shutdown();
47  // Always shutdown the completion queue after the server.
48  cq_->Shutdown();
49  }
50 
51  // There is no shutdown handling in this code.
52  void Run() {
53  std::string server_address("0.0.0.0:50051");
54 
56  // Listen on the given address without any authentication mechanism.
58  // Register "service_" as the instance through which we'll communicate with
59  // clients. In this case it corresponds to an *asynchronous* service.
60  builder.RegisterService(&service_);
61  // Get hold of the completion queue used for the asynchronous communication
62  // with the gRPC runtime.
63  cq_ = builder.AddCompletionQueue();
64  // Finally assemble the server.
65  server_ = builder.BuildAndStart();
66  std::cout << "Server listening on " << server_address << std::endl;
67 
68  // Proceed to the server's main loop.
69  HandleRpcs();
70  }
71 
72  private:
73  // Class encompasing the state and logic needed to serve a request.
74  class CallData {
75  public:
76  // Take in the "service" instance (in this case representing an asynchronous
77  // server) and the completion queue "cq" used for asynchronous communication
78  // with the gRPC runtime.
79  CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq)
81  // Invoke the serving logic right away.
82  Proceed();
83  }
84 
85  void Proceed() {
86  if (status_ == CREATE) {
87  // Make this instance progress to the PROCESS state.
88  status_ = PROCESS;
89 
90  // As part of the initial CREATE state, we *request* that the system
91  // start processing SayHello requests. In this request, "this" acts are
92  // the tag uniquely identifying the request (so that different CallData
93  // instances can serve different requests concurrently), in this case
94  // the memory address of this CallData instance.
95  service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,
96  this);
97  } else if (status_ == PROCESS) {
98  // Spawn a new CallData instance to serve new clients while we process
99  // the one for this CallData. The instance will deallocate itself as
100  // part of its FINISH state.
101  new CallData(service_, cq_);
102 
103  // The actual processing.
104  std::string prefix("Hello ");
105  reply_.set_message(prefix + request_.name());
106 
107  // And we are done! Let the gRPC runtime know we've finished, using the
108  // memory address of this instance as the uniquely identifying tag for
109  // the event.
110  status_ = FINISH;
112  } else {
114  // Once in the FINISH state, deallocate ourselves (CallData).
115  delete this;
116  }
117  }
118 
119  private:
120  // The means of communication with the gRPC runtime for an asynchronous
121  // server.
122  Greeter::AsyncService* service_;
123  // The producer-consumer queue where for asynchronous server notifications.
125  // Context for the rpc, allowing to tweak aspects of it such as the use
126  // of compression, authentication, as well as to send metadata back to the
127  // client.
129 
130  // What we get from the client.
132  // What we send back to the client.
134 
135  // The means to get back to the client.
137 
138  // Let's implement a tiny state machine with the following states.
140  CallStatus status_; // The current serving state.
141  };
142 
143  // This can be run in multiple threads if needed.
144  void HandleRpcs() {
145  // Spawn a new CallData instance to serve new clients.
146  new CallData(&service_, cq_.get());
147  void* tag; // uniquely identifies a request.
148  bool ok;
149  while (true) {
150  // Block waiting to read the next event from the completion queue. The
151  // event is uniquely identified by its tag, which in this case is the
152  // memory address of a CallData instance.
153  // The return value of Next should always be checked. This return value
154  // tells us whether there is any kind of event or cq_ is shutting down.
155  GPR_ASSERT(cq_->Next(&tag, &ok));
156  GPR_ASSERT(ok);
157  static_cast<CallData*>(tag)->Proceed();
158  }
159  }
160 
161  std::unique_ptr<ServerCompletionQueue> cq_;
162  Greeter::AsyncService service_;
163  std::unique_ptr<Server> server_;
164 };
165 
166 int main(int argc, char** argv) {
168  server.Run();
169 
170  return 0;
171 }
grpc::ServerCompletionQueue
Definition: include/grpcpp/impl/codegen/completion_queue.h:436
grpc::ServerContext
Definition: grpcpp/impl/codegen/server_context.h:566
log.h
ServerImpl::CallData::cq_
ServerCompletionQueue * cq_
Definition: greeter_async_server.cc:124
main
int main(int argc, char **argv)
Definition: greeter_async_server.cc:166
ServerImpl
Definition: greeter_async_server.cc:43
ServerImpl::CallData::responder_
ServerAsyncResponseWriter< HelloReply > responder_
Definition: greeter_async_server.cc:136
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
ServerImpl::CallData
Definition: greeter_async_server.cc:74
framework.rpc.grpc_channelz.Server
Server
Definition: grpc_channelz.py:42
hellostreamingworld_pb2.HelloRequest
HelloRequest
Definition: hellostreamingworld_pb2.py:102
OK
@ OK
Definition: cronet_status.h:43
ServerImpl::CallData::CREATE
@ CREATE
Definition: greeter_async_server.cc:139
server_address
std::string server_address("0.0.0.0:10000")
ServerImpl::CallData::request_
HelloRequest request_
Definition: greeter_async_server.cc:131
ServerImpl::CallData::ctx_
ServerContext ctx_
Definition: greeter_async_server.cc:128
server
std::unique_ptr< Server > server
Definition: channelz_service_test.cc:330
ServerImpl::CallData::status_
CallStatus status_
Definition: greeter_async_server.cc:140
ServerImpl::CallData::FINISH
@ FINISH
Definition: greeter_async_server.cc:139
profile_analyzer.builder
builder
Definition: profile_analyzer.py:159
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
grpc::ServerBuilder
A builder class for the creation and startup of grpc::Server instances.
Definition: grpcpp/server_builder.h:86
ServerImpl::CallData::service_
Greeter::AsyncService * service_
Definition: greeter_async_server.cc:122
ServerImpl::service_
Greeter::AsyncService service_
Definition: greeter_async_server.cc:162
grpcpp.h
ServerImpl::server_
std::unique_ptr< Server > server_
Definition: greeter_async_server.cc:163
ServerImpl::CallData::PROCESS
@ PROCESS
Definition: greeter_async_server.cc:139
helloworld.Greeter
Definition: helloworld.py:32
grpc::ServerAsyncResponseWriter::Finish
void Finish(const W &msg, const grpc::Status &status, void *tag)
Definition: grpcpp/impl/codegen/async_unary_call.h:340
hellostreamingworld_pb2.HelloReply
HelloReply
Definition: hellostreamingworld_pb2.py:109
ServerImpl::CallData::CallStatus
CallStatus
Definition: greeter_async_server.cc:139
server
Definition: examples/python/async_streaming/server.py:1
ServerImpl::~ServerImpl
~ServerImpl()
Definition: greeter_async_server.cc:45
prefix
static const char prefix[]
Definition: head_of_line_blocking.cc:28
grpc::protobuf::util::Status
GRPC_CUSTOM_UTIL_STATUS Status
Definition: include/grpcpp/impl/codegen/config_protobuf.h:93
ok
bool ok
Definition: async_end2end_test.cc:197
ServerImpl::Run
void Run()
Definition: greeter_async_server.cc:52
grpc::InsecureServerCredentials
std::shared_ptr< ServerCredentials > InsecureServerCredentials()
Definition: insecure_server_credentials.cc:52
ServerImpl::CallData::Proceed
void Proceed()
Definition: greeter_async_server.cc:85
ServerImpl::HandleRpcs
void HandleRpcs()
Definition: greeter_async_server.cc:144
grpc::ServerAsyncResponseWriter
Definition: grpcpp/impl/codegen/async_unary_call.h:295
service
__attribute__((deprecated("Please use GRPCProtoMethod."))) @interface ProtoMethod NSString * service
Definition: ProtoMethod.h:25
ServerImpl::cq_
std::unique_ptr< ServerCompletionQueue > cq_
Definition: greeter_async_server.cc:161
ServerImpl::CallData::CallData
CallData(Greeter::AsyncService *service, ServerCompletionQueue *cq)
Definition: greeter_async_server.cc:79
ServerImpl::CallData::reply_
HelloReply reply_
Definition: greeter_async_server.cc:133
cq
static grpc_completion_queue * cq
Definition: test/core/fling/client.cc:37


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:47