• rpc中的callmethod函数


    转自:https://blog.csdn.net/nk_test/article/details/72682780

    1.CallMethod

    在客户端生成的存根类Stub,实际上通过callmethod来实现的调用远程方法,

    void EchoService_Stub::Foo(::google::protobuf::RpcController* controller,
                                  const ::FooRequest* request,
                                  ::FooResponse* response,
                                  ::google::protobuf::Closure* done) {
      channel_->CallMethod(descriptor()->method(0),
                           controller, request, response, done);
    }

    所以框架的实现重点就在于RpcChannel的CallMethod方法,发送请求就是在这个函数中完成的。

    Muduo中的CallMethod的实现:

    void RpcChannel::CallMethod(const ::google::protobuf::MethodDescriptor* method,
                                google::protobuf::RpcController* controller,
                                const ::google::protobuf::Message* request,
                                ::google::protobuf::Message* response,
                                ::google::protobuf::Closure* done)
    {
      RpcMessage message;
      message.set_type(REQUEST);
      int64_t id = id_.incrementAndGet();
      message.set_id(id);
      message.set_service(method->service()->full_name());//获取服务的方法名
      message.set_method(method->name());//获取方法名
      message.set_request(request->SerializeAsString()); // FIXME: error check
    
      OutstandingCall out = { response, done };
      {
      MutexLockGuard lock(mutex_);
      outstandings_[id] = out;
      }
      codec_.send(conn_, message);//发送数据
    }

    CallMethod中除了发送数据之外,参数还有一个MethodDescriptor类,这是用来标识哪一个service的。

    例如,如果定义了多个service,那么每个service的请求包和回复包都是protobuf中的message结构体,在这个例子中是EchoRequest和EchoResponse message。可是,它们仅仅是包体,也就是说,即使你发送了这些消息,在服务器端还需要一个包头来识别到底是哪个请求的包体,然后再进行具体的调用处理。如,

    void EchoService::CallMethod(const ::google::protobuf::MethodDescriptor* method,
                                 ::google::protobuf::RpcController* controller,
                                 const ::google::protobuf::Message* request,
                                 ::google::protobuf::Message* response,
                                 ::google::protobuf::Closure* done) {
      GOOGLE_DCHECK_EQ(method->service(), EchoService_descriptor_);
      switch(method->index()) {
        case 0:
          Echo(controller,
                 ::google::protobuf::down_cast<CONST ::echo::EchoRequest*>(request),
                 ::google::protobuf::down_cast< ::echo::EchoResponse*>(response),
                 done);
          break;
        default:
          GOOGLE_LOG(FATAL) << "Bad method index; this should never happen.";
          break;
      }
    }

    //没太看懂这个callmethod,怎么是EchoService类的函数呢?那还是在客户端生成的吗?那case 0的时候调用的Echo也是客户端的代码吗?还是说也是存根stub?看起来像是,那这个Echo具体还要调用rpc的callmethod方法?这里的EchoService的callmethod只是相当于一个代理?

  • 相关阅读:
    Block详解二(底层分析)
    Block详解一(底层分析)
    Swift 属性与汇编分析inout本质
    Swift --闭包表达式与闭包(汇编分析)
    Swift--struct与class的区别(汇编角度底层分析)
    Swift 枚举-从汇编角度看枚举内存结构
    Swift -POP( 面向协议编程)与OOP(面向对象编程)
    从零开始的计算机网络基础(图文并茂,1.8w字,面试复习必备)
    浅谈js数据类型
    js数组冷知识
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/16633168.html
Copyright © 2020-2023  润新知