blob: fe0a2139297c1ed4fe43f76e2eeea63673d6e0d6 [file] [log] [blame]
Michael Yeh470cbd12016-05-04 12:39:20 -07001/*
2 *
3 * Copyright 2015, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include <iostream>
35#include <memory>
36#include <string>
37
38#include <grpc++/grpc++.h>
Stanley Cheungc9b401e2016-09-15 21:19:53 -070039#include <grpc/support/log.h>
Michael Yeh470cbd12016-05-04 12:39:20 -070040#include <thread>
41
42#include "helloworld.grpc.pb.h"
43
44using grpc::Channel;
45using grpc::ClientAsyncResponseReader;
46using grpc::ClientContext;
47using grpc::CompletionQueue;
48using grpc::Status;
49using helloworld::HelloRequest;
50using helloworld::HelloReply;
51using helloworld::Greeter;
52
53class GreeterClient {
54 public:
55 explicit GreeterClient(std::shared_ptr<Channel> channel)
56 : stub_(Greeter::NewStub(channel)) {}
57
Michael Yehf9b89b12016-05-04 16:36:20 -070058 // Assembles the client's payload and sends it to the server.
Michael Yeh470cbd12016-05-04 12:39:20 -070059 void SayHello(const std::string& user) {
60 // Data we are sending to the server.
61 HelloRequest request;
62 request.set_name(user);
63
Michael Yehf9b89b12016-05-04 16:36:20 -070064 // Call object to store rpc data
Michael Yeh470cbd12016-05-04 12:39:20 -070065 AsyncClientCall* call = new AsyncClientCall;
66
Michael Yehf9b89b12016-05-04 16:36:20 -070067 // stub_->AsyncSayHello() performs the RPC call, returning an instance to
68 // store in "call". Because we are using the asynchronous API, we need to
69 // hold on to the "call" instance in order to get updates on the ongoing RPC.
Michael Yeh470cbd12016-05-04 12:39:20 -070070 call->response_reader = stub_->AsyncSayHello(&call->context, request, &cq_);
71
72
73 // Request that, upon completion of the RPC, "reply" be updated with the
74 // server's response; "status" with the indication of whether the operation
Michael Yehf9b89b12016-05-04 16:36:20 -070075 // was successful. Tag the request with the memory address of the call object.
Michael Yeh470cbd12016-05-04 12:39:20 -070076 call->response_reader->Finish(&call->reply, &call->status, (void*)call);
77
78 }
79
Michael Yehf9b89b12016-05-04 16:36:20 -070080 // Loop while listening for completed responses.
81 // Prints out the response from the server.
82 void AsyncCompleteRpc() {
Michael Yeh470cbd12016-05-04 12:39:20 -070083 void* got_tag;
84 bool ok = false;
85
86 // Block until the next result is available in the completion queue "cq".
Michael Yehf9b89b12016-05-04 16:36:20 -070087 while (cq_.Next(&got_tag, &ok)) {
88 // The tag in this example is the memory location of the call object
Michael Yeh470cbd12016-05-04 12:39:20 -070089 AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag);
Michael Yehf9b89b12016-05-04 16:36:20 -070090
91 // Verify that the request was completed successfully. Note that "ok"
92 // corresponds solely to the request for updates introduced by Finish().
93 GPR_ASSERT(ok);
94
95 if (call->status.ok())
Michael Yeh470cbd12016-05-04 12:39:20 -070096 std::cout << "Greeter received: " << call->reply.message() << std::endl;
97 else
98 std::cout << "RPC failed" << std::endl;
Michael Yehf9b89b12016-05-04 16:36:20 -070099
100 // Once we're complete, deallocate the call object.
Michael Yeh470cbd12016-05-04 12:39:20 -0700101 delete call;
102 }
103 }
104
105 private:
106
107 // struct for keeping state and data information
Michael Yehf9b89b12016-05-04 16:36:20 -0700108 struct AsyncClientCall {
Michael Yeh470cbd12016-05-04 12:39:20 -0700109 // Container for the data we expect from the server.
110 HelloReply reply;
111
112 // Context for the client. It could be used to convey extra information to
113 // the server and/or tweak certain RPC behaviors.
114 ClientContext context;
115
116 // Storage for the status of the RPC upon completion.
117 Status status;
118
119
120 std::unique_ptr<ClientAsyncResponseReader<HelloReply>> response_reader;
121 };
122
123 // Out of the passed in Channel comes the stub, stored here, our view of the
124 // server's exposed services.
125 std::unique_ptr<Greeter::Stub> stub_;
126
127 // The producer-consumer queue we use to communicate asynchronously with the
128 // gRPC runtime.
129 CompletionQueue cq_;
130};
131
132int main(int argc, char** argv) {
133
134
135 // Instantiate the client. It requires a channel, out of which the actual RPCs
136 // are created. This channel models a connection to an endpoint (in this case,
137 // localhost at port 50051). We indicate that the channel isn't authenticated
138 // (use of InsecureChannelCredentials()).
139 GreeterClient greeter(grpc::CreateChannel(
140 "localhost:50051", grpc::InsecureChannelCredentials()));
141
142 // Spawn reader thread that loops indefinitely
143 std::thread thread_ = std::thread(&GreeterClient::AsyncCompleteRpc, &greeter);
144
Michael Yehf9b89b12016-05-04 16:36:20 -0700145 for (int i = 0; i < 100; i++) {
Michael Yeh470cbd12016-05-04 12:39:20 -0700146 std::string user("world " + std::to_string(i));
147 greeter.SayHello(user); // The actual RPC call!
148 }
149
150 std::cout << "Press control-c to quit" << std::endl << std::endl;
151 thread_.join(); //blocks forever
152
153 return 0;
154}