• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# gRPC C++ Hello World Tutorial
2
3### Install gRPC
4Make sure you have installed gRPC on your system. Follow the
5[BUILDING.md](../../../BUILDING.md) instructions.
6
7### Get the tutorial source code
8
9The example code for this and our other examples lives in the `examples`
10directory. Clone this repository to your local machine by running the
11following command:
12
13
14```sh
15$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
16```
17
18Change your current directory to examples/cpp/helloworld
19
20```sh
21$ cd examples/cpp/helloworld/
22```
23
24### Defining a service
25
26The first step in creating our example is to define a *service*: an RPC
27service specifies the methods that can be called remotely with their parameters
28and return types. As you saw in the
29[overview](#protocolbuffers) above, gRPC does this using [protocol
30buffers](https://developers.google.com/protocol-buffers/docs/overview). We
31use the protocol buffers interface definition language (IDL) to define our
32service methods, and define the parameters and return
33types as protocol buffer message types. Both the client and the
34server use interface code generated from the service definition.
35
36Here's our example service definition, defined using protocol buffers IDL in
37[helloworld.proto](../../protos/helloworld.proto). The `Greeting`
38service has one method, `hello`, that lets the server receive a single
39`HelloRequest`
40message from the remote client containing the user's name, then send back
41a greeting in a single `HelloReply`. This is the simplest type of RPC you
42can specify in gRPC - we'll look at some other types later in this document.
43
44```protobuf
45syntax = "proto3";
46
47option java_package = "ex.grpc";
48
49package helloworld;
50
51// The greeting service definition.
52service Greeter {
53  // Sends a greeting
54  rpc SayHello (HelloRequest) returns (HelloReply) {}
55}
56
57// The request message containing the user's name.
58message HelloRequest {
59  string name = 1;
60}
61
62// The response message containing the greetings
63message HelloReply {
64  string message = 1;
65}
66
67```
68
69<a name="generating"></a>
70### Generating gRPC code
71
72Once we've defined our service, we use the protocol buffer compiler
73`protoc` to generate the special client and server code we need to create
74our application. The generated code contains both stub code for clients to
75use and an abstract interface for servers to implement, both with the method
76defined in our `Greeting` service.
77
78To generate the client and server side interfaces:
79
80```sh
81$ make helloworld.grpc.pb.cc helloworld.pb.cc
82```
83Which internally invokes the proto-compiler as:
84
85```sh
86$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto
87$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto
88```
89
90### Writing a client
91
92- Create a channel. A channel is a logical connection to an endpoint. A gRPC
93  channel can be created with the target address, credentials to use and
94  arguments as follows
95
96    ```cpp
97    auto channel = CreateChannel("localhost:50051", InsecureChannelCredentials());
98    ```
99
100- Create a stub. A stub implements the rpc methods of a service and in the
101  generated code, a method is provided to created a stub with a channel:
102
103    ```cpp
104    auto stub = helloworld::Greeter::NewStub(channel);
105    ```
106
107- Make a unary rpc, with `ClientContext` and request/response proto messages.
108
109    ```cpp
110    ClientContext context;
111    HelloRequest request;
112    request.set_name("hello");
113    HelloReply reply;
114    Status status = stub->SayHello(&context, request, &reply);
115    ```
116
117- Check returned status and response.
118
119    ```cpp
120    if (status.ok()) {
121      // check reply.message()
122    } else {
123      // rpc failed.
124    }
125    ```
126
127For a working example, refer to [greeter_client.cc](greeter_client.cc).
128
129### Writing a server
130
131- Implement the service interface
132
133    ```cpp
134    class GreeterServiceImpl final : public Greeter::Service {
135      Status SayHello(ServerContext* context, const HelloRequest* request,
136          HelloReply* reply) override {
137        std::string prefix("Hello ");
138        reply->set_message(prefix + request->name());
139        return Status::OK;
140      }
141    };
142
143    ```
144
145- Build a server exporting the service
146
147    ```cpp
148    GreeterServiceImpl service;
149    ServerBuilder builder;
150    builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials());
151    builder.RegisterService(&service);
152    std::unique_ptr<Server> server(builder.BuildAndStart());
153    ```
154
155For a working example, refer to [greeter_server.cc](greeter_server.cc).
156
157### Writing asynchronous client and server
158
159gRPC uses `CompletionQueue` API for asynchronous operations. The basic work flow
160is
161- bind a `CompletionQueue` to a rpc call
162- do something like a read or write, present with a unique `void*` tag
163- call `CompletionQueue::Next` to wait for operations to complete. If a tag
164  appears, it indicates that the corresponding operation is complete.
165
166#### Async client
167
168The channel and stub creation code is the same as the sync client.
169
170- Initiate the rpc and create a handle for the rpc. Bind the rpc to a
171  `CompletionQueue`.
172
173    ```cpp
174    CompletionQueue cq;
175    auto rpc = stub->AsyncSayHello(&context, request, &cq);
176    ```
177
178- Ask for reply and final status, with a unique tag
179
180    ```cpp
181    Status status;
182    rpc->Finish(&reply, &status, (void*)1);
183    ```
184
185- Wait for the completion queue to return the next tag. The reply and status are
186  ready once the tag passed into the corresponding `Finish()` call is returned.
187
188    ```cpp
189    void* got_tag;
190    bool ok = false;
191    cq.Next(&got_tag, &ok);
192    if (ok && got_tag == (void*)1) {
193      // check reply and status
194    }
195    ```
196
197For a working example, refer to [greeter_async_client.cc](greeter_async_client.cc).
198
199#### Async server
200
201The server implementation requests a rpc call with a tag and then wait for the
202completion queue to return the tag. The basic flow is
203
204- Build a server exporting the async service
205
206    ```cpp
207    helloworld::Greeter::AsyncService service;
208    ServerBuilder builder;
209    builder.AddListeningPort("0.0.0.0:50051", InsecureServerCredentials());
210    builder.RegisterService(&service);
211    auto cq = builder.AddCompletionQueue();
212    auto server = builder.BuildAndStart();
213    ```
214
215- Request one rpc
216
217    ```cpp
218    ServerContext context;
219    HelloRequest request;
220    ServerAsyncResponseWriter<HelloReply> responder;
221    service.RequestSayHello(&context, &request, &responder, &cq, &cq, (void*)1);
222    ```
223
224- Wait for the completion queue to return the tag. The context, request and
225  responder are ready once the tag is retrieved.
226
227    ```cpp
228    HelloReply reply;
229    Status status;
230    void* got_tag;
231    bool ok = false;
232    cq.Next(&got_tag, &ok);
233    if (ok && got_tag == (void*)1) {
234      // set reply and status
235      responder.Finish(reply, status, (void*)2);
236    }
237    ```
238
239- Wait for the completion queue to return the tag. The rpc is finished when the
240  tag is back.
241
242    ```cpp
243    void* got_tag;
244    bool ok = false;
245    cq.Next(&got_tag, &ok);
246    if (ok && got_tag == (void*)2) {
247      // clean up
248    }
249    ```
250
251To handle multiple rpcs, the async server creates an object `CallData` to
252maintain the state of each rpc and use the address of it as the unique tag. For
253simplicity the server only uses one completion queue for all events, and runs a
254main loop in `HandleRpcs` to query the queue.
255
256For a working example, refer to [greeter_async_server.cc](greeter_async_server.cc).
257
258
259
260
261