client.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. 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,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. // A client to send 2 requests to server and accept the first returned response.
  18. #include <gflags/gflags.h>
  19. #include <butil/logging.h>
  20. #include <butil/time.h>
  21. #include <brpc/channel.h>
  22. #include "echo.pb.h"
  23. DEFINE_string(protocol, "baidu_std", "Protocol type. Defined in src/brpc/options.proto");
  24. DEFINE_string(connection_type, "", "Connection type. Available values: single, pooled, short");
  25. DEFINE_string(server, "0.0.0.0:8000", "IP Address of server");
  26. DEFINE_string(load_balancer, "", "The algorithm for load balancing");
  27. DEFINE_int32(timeout_ms, 100, "RPC timeout in milliseconds");
  28. DEFINE_int32(max_retry, 3, "Max retries(not including the first RPC)");
  29. // A special done for canceling another RPC.
  30. class CancelRPC : public google::protobuf::Closure {
  31. public:
  32. explicit CancelRPC(brpc::CallId rpc_id) : _rpc_id(rpc_id) {}
  33. void Run() {
  34. brpc::StartCancel(_rpc_id);
  35. }
  36. private:
  37. brpc::CallId _rpc_id;
  38. };
  39. int main(int argc, char* argv[]) {
  40. // Parse gflags. We recommend you to use gflags as well.
  41. GFLAGS_NS::ParseCommandLineFlags(&argc, &argv, true);
  42. // A Channel represents a communication line to a Server. Notice that
  43. // Channel is thread-safe and can be shared by all threads in your program.
  44. brpc::Channel channel;
  45. // Initialize the channel, NULL means using default options.
  46. brpc::ChannelOptions options;
  47. options.protocol = FLAGS_protocol;
  48. options.connection_type = FLAGS_connection_type;
  49. options.timeout_ms = FLAGS_timeout_ms/*milliseconds*/;
  50. options.max_retry = FLAGS_max_retry;
  51. if (channel.Init(FLAGS_server.c_str(), FLAGS_load_balancer.c_str(), &options) != 0) {
  52. LOG(ERROR) << "Fail to initialize channel";
  53. return -1;
  54. }
  55. // Normally, you should not call a Channel directly, but instead construct
  56. // a stub Service wrapping it. stub can be shared by all threads as well.
  57. example::EchoService_Stub stub(&channel);
  58. // Send a request and wait for the response every 1 second.
  59. int log_id = 0;
  60. while (!brpc::IsAskedToQuit()) {
  61. example::EchoRequest request1;
  62. example::EchoResponse response1;
  63. brpc::Controller cntl1;
  64. example::EchoRequest request2;
  65. example::EchoResponse response2;
  66. brpc::Controller cntl2;
  67. request1.set_message("hello1");
  68. request2.set_message("hello2");
  69. cntl1.set_log_id(log_id ++); // set by user
  70. cntl2.set_log_id(log_id ++);
  71. const brpc::CallId id1 = cntl1.call_id();
  72. const brpc::CallId id2 = cntl2.call_id();
  73. CancelRPC done1(id2);
  74. CancelRPC done2(id1);
  75. butil::Timer tm;
  76. tm.start();
  77. // Send 2 async calls and join them. They will cancel each other in
  78. // their done which is run before the RPC being Join()-ed. Canceling
  79. // a finished RPC has no effect.
  80. // For example:
  81. // Time RPC1 RPC2
  82. // 1 response1 comes back.
  83. // 2 running done1.
  84. // 3 cancel RPC2
  85. // 4 running done2 (NOTE: done also runs)
  86. // 5 cancel RPC1 (no effect)
  87. stub.Echo(&cntl1, &request1, &response1, &done1);
  88. stub.Echo(&cntl2, &request2, &response2, &done2);
  89. brpc::Join(id1);
  90. brpc::Join(id2);
  91. tm.stop();
  92. if (cntl1.Failed() && cntl2.Failed()) {
  93. LOG(WARNING) << "Both failed. rpc1:" << cntl1.ErrorText()
  94. << ", rpc2: " << cntl2.ErrorText();
  95. } else if (!cntl1.Failed()) {
  96. LOG(INFO) << "Received `" << response1.message() << "' from rpc1="
  97. << id1.value << '@' << cntl1.remote_side()
  98. << " latency=" << tm.u_elapsed() << "us"
  99. << " rpc1_latency=" << cntl1.latency_us() << "us"
  100. << " rpc2_latency=" << cntl2.latency_us() << "us";
  101. } else {
  102. LOG(INFO) << "Received `" << response2.message() << "' from rpc2="
  103. << id2.value << '@' << cntl2.remote_side()
  104. << " latency=" << tm.u_elapsed() << "us"
  105. << " rpc1_latency=" << cntl1.latency_us() << "us"
  106. << " rpc2_latency=" << cntl2.latency_us() << "us";
  107. }
  108. sleep(1);
  109. }
  110. LOG(INFO) << "EchoClient is going to quit";
  111. return 0;
  112. }