• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <grpcpp/grpcpp.h>
16 
17 #include <condition_variable>
18 #include <iostream>
19 #include <memory>
20 #include <mutex>
21 #include <string>
22 #include <vector>
23 
24 #include "absl/flags/flag.h"
25 #include "absl/flags/parse.h"
26 #include "absl/strings/str_cat.h"
27 
28 #ifdef BAZEL_BUILD
29 #include "examples/protos/helloworld.grpc.pb.h"
30 #else
31 #include "helloworld.grpc.pb.h"
32 #endif
33 
34 ABSL_FLAG(std::string, target, "localhost:50051", "Server address");
35 
36 using grpc::Channel;
37 using grpc::ClientContext;
38 using grpc::Status;
39 using grpc::StatusCode;
40 using helloworld::Greeter;
41 using helloworld::HelloReply;
42 using helloworld::HelloRequest;
43 
44 // Requests each key in the vector and displays the key and its corresponding
45 // value as a pair.
46 class KeyValueStoreClient
47     : public grpc::ClientBidiReactor<HelloRequest, HelloReply> {
48  public:
KeyValueStoreClient(std::shared_ptr<Channel> channel)49   KeyValueStoreClient(std::shared_ptr<Channel> channel)
50       : stub_(Greeter::NewStub(channel)) {
51     stub_->async()->SayHelloBidiStream(&context_, this);
52     request_.set_name("Begin");
53     StartWrite(&request_);
54     StartCall();
55   }
56 
OnReadDone(bool ok)57   void OnReadDone(bool ok) override {
58     if (ok) {
59       std::cout << request_.name() << " : " << response_.message() << std::endl;
60       if (++counter_ < 10) {
61         request_.set_name(absl::StrCat("Count ", counter_));
62         StartWrite(&request_);
63       } else {
64         // Cancel after sending 10 messages
65         context_.TryCancel();
66       }
67     }
68   }
69 
OnWriteDone(bool ok)70   void OnWriteDone(bool ok) override {
71     if (ok) {
72       StartRead(&response_);
73     }
74   }
75 
OnDone(const grpc::Status & status)76   void OnDone(const grpc::Status& status) override {
77     if (!status.ok()) {
78       if (status.error_code() == StatusCode::CANCELLED) {
79         // Eventually client will know here that call is cancelled.
80         std::cout << "RPC Cancelled!" << std::endl;
81       } else {
82         std::cout << "RPC Failed: " << status.error_code() << ": "
83                   << status.error_message() << std::endl;
84       }
85     }
86     std::unique_lock<std::mutex> l(mu_);
87     done_ = true;
88     cv_.notify_all();
89   }
90 
Await()91   void Await() {
92     std::unique_lock<std::mutex> l(mu_);
93     while (!done_) {
94       cv_.wait(l);
95     }
96   }
97 
98  private:
99   std::unique_ptr<Greeter::Stub> stub_;
100   size_t counter_ = 0;
101   ClientContext context_;
102   bool done_ = false;
103   HelloRequest request_;
104   HelloReply response_;
105   std::mutex mu_;
106   std::condition_variable cv_;
107 };
108 
main(int argc,char ** argv)109 int main(int argc, char** argv) {
110   absl::ParseCommandLine(argc, argv);
111   // Instantiate the client. It requires a channel, out of which the actual RPCs
112   // are created. This channel models a connection to an endpoint specified by
113   // the argument "--target=" which is the only expected argument.
114   std::string target_str = absl::GetFlag(FLAGS_target);
115   KeyValueStoreClient client(
116       grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials()));
117   client.Await();
118   return 0;
119 }
120