brpc : example-echo-c++

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chj90220/article/details/81124091

https://github.com/brpc/brpc/tree/master/example/echo_c%2B%2B

这里学习下brpc的example:echo-c++。先学会使用brpc,载了解了brpc的基本特性之后,再去深入研究。

client

https://github.com/brpc/brpc/blob/master/docs/cn/client.md

无论是client还是server,均使用gflags解析命令行参数。例如:

DEFINE_int32(timeout_ms, 100, "RPC timeout in milliseconds");

这定义了一个名称为timeout_ms的命令行参数,默认值是100,帮助信息为最后一个字符串参数。定义好之后,在main函数中通过如下语句解析命令行参数:

GFLAGS_NS::ParseCommandLineFlags(&argc, &argv, true);

之后可以使用FLAGS_timeout_ms(给timeout_ms加上FLAGS_前缀) 来获取此变量的值。看来gflags挺便利的。

Channel

    // A Channel represents a communication line to a Server. Notice that 
    // Channel is thread-safe and can be shared by all threads in your program.
    brpc::Channel channel;

client首先创建了一个brpc::Channel,翻译下注释:Channel是与Server通信的通道。Channel时thread-safe的,可以被多个线程共享。

接下来对Channel进行类初始化,用到了上面定义的命令行参数,主要包括:协议类型、连接类型、超时时间、重试次数、服务器地址、负载均衡策略。(功能挺丰富的)

    // Initialize the channel, NULL means using default options.
    brpc::ChannelOptions options;
    options.protocol = FLAGS_protocol;
    options.connection_type = FLAGS_connection_type;
    options.timeout_ms = FLAGS_timeout_ms/*milliseconds*/;
    options.max_retry = FLAGS_max_retry;
    if (channel.Init(FLAGS_server.c_str(), FLAGS_load_balancer.c_str(), &options) != 0) {
        LOG(ERROR) << "Fail to initialize channel";
        return -1;
    }

接着将Channel传递给Stub类,这里涉及到protobuf service的相关知识,可以移步这里.

    // Normally, you should not call a Channel directly, but instead construct
    // a stub Service wrapping it. stub can be shared by all threads as well.
    example::EchoService_Stub stub(&channel);

通常并不直接使用Channel,而是把Channel传递给一个stub service,注意stub也可以被多个线程共享。

最后,通过Stub的Echo接口发送请求,并接收响应。

        example::EchoRequest request;
        example::EchoResponse response;
        brpc::Controller cntl;

        request.set_message("hello world");

        // Because `done'(last parameter) is NULL, this function waits until
        // the response comes back or error occurs(including timedout).
        stub.Echo(&cntl, &request, &response, NULL);
        if (!cntl.Failed()) {
            LOG(INFO) << "Received response from " << cntl.remote_side()
                << " to " << cntl.local_side()
                << ": " << response.message() << " (attached="
                << cntl.response_attachment() << ")"
                << " latency=" << cntl.latency_us() << "us";
        } else {
            LOG(WARNING) << cntl.ErrorText();
        }

实际上,Stub::Echo最终会调用Channel::CallMethod,这是protobuf生成service时自动生成的代码:

void EchoService_Stub::Echo(::google::protobuf::RpcController* controller,
                              const ::example::EchoRequest* request,
                              ::example::EchoResponse* response,
                              ::google::protobuf::Closure* done) {
  channel_->CallMethod(descriptor()->method(0),
                       controller, request, response, done);
}

brpc::Channel::CallMethod

    // Call `method' of the remote service with `request' as input, and 
    // `response' as output. `controller' contains options and extra data.
    // If `done' is not NULL, this method returns after request was sent
    // and `done->Run()' will be called when the call finishes, otherwise
    // caller blocks until the call finishes.
    void CallMethod(const google::protobuf::MethodDescriptor* method,
                    google::protobuf::RpcController* controller,
                    const google::protobuf::Message* request,
                    google::protobuf::Message* response,
                    google::protobuf::Closure* done);

protobuf的service生成的框架代码决定了,客户端要给Stub类传递一个Channel,Stub会调用Channel的CallMethod。因此client需要实现Channel::CallMethod。

baidu_std

client的命令行参数protocol默认使用的协议为baidu_std, 该协议的定义在src/brpc/options.proto

https://github.com/brpc/brpc/blob/master/docs/cn/baidu_std.md

brpc::Controller

展开阅读全文

没有更多推荐了,返回首页