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只是相当于一个代理?

 

posted @ 2022-08-28 17:28  lypbendlf  阅读(261)  评论(0编辑  收藏  举报