概述
背景
本地服务想要发布到rpc框架上,要首先本地定义proto文件,将要发布在rpc框架上的方法写入相应的service中。
service UserServiceRpc
{
rpc login(LoginRequest) returns(LoginResponse);
rpc Register(RegisterRequest) returns(RegisterResponse);
}
这里面定义了一个UserServiceRpc,里面包含两个方法login和Register。proto文件结果protoc编译后,相应的service会生成两个类,class UserServiceRpc 和class UserServiceRpc_stub。
class UserServiceRpc : public ::PROTOBUF_NAMESPACE_ID::Service {
protected:
// This class should be treated as an abstract interface.
inline UserServiceRpc() {};
public:
virtual ~UserServiceRpc();
typedef UserServiceRpc_Stub Stub;
static const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor* descriptor();
virtual void login(::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::taoye::LoginRequest* request,
::taoye::LoginResponse* response,
::google::protobuf::Closure* done);
virtual void Register(::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::taoye::RegisterRequest* request,
::taoye::RegisterResponse* response,
::google::protobuf::Closure* done);
// implements Service ----------------------------------------------
const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor* GetDescriptor();
void CallMethod(const ::PROTOBUF_NAMESPACE_ID::MethodDescriptor* method,
::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::PROTOBUF_NAMESPACE_ID::Message* request,
::PROTOBUF_NAMESPACE_ID::Message* response,
::google::protobuf::Closure* done);
const ::PROTOBUF_NAMESPACE_ID::Message& GetRequestPrototype(
const ::PROTOBUF_NAMESPACE_ID::MethodDescriptor* method) const;
const ::PROTOBUF_NAMESPACE_ID::Message& GetResponsePrototype(
const ::PROTOBUF_NAMESPACE_ID::MethodDescriptor* method) const;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UserServiceRpc);
};
class UserServiceRpc_Stub : public UserServiceRpc {
public:
UserServiceRpc_Stub(::PROTOBUF_NAMESPACE_ID::RpcChannel* channel);
UserServiceRpc_Stub(::PROTOBUF_NAMESPACE_ID::RpcChannel* channel,
::PROTOBUF_NAMESPACE_ID::Service::ChannelOwnership ownership);
~UserServiceRpc_Stub();
inline ::PROTOBUF_NAMESPACE_ID::RpcChannel* channel() { return channel_; }
// implements UserServiceRpc ------------------------------------------
void login(::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::taoye::LoginRequest* request,
::taoye::LoginResponse* response,
::google::protobuf::Closure* done);
void Register(::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::taoye::RegisterRequest* request,
::taoye::RegisterResponse* response,
::google::protobuf::Closure* done);
private:
::PROTOBUF_NAMESPACE_ID::RpcChannel* channel_;
bool owns_channel_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UserServiceRpc_Stub);
};
发现UserServiceRpc 是继承于protobuf提供的service基类,而UserServiceRpc_stub是继承于UserServiceRpc ,就是说这两个类都是继承于service这个基类。
分别研究UserServiceRpc 和UserServiceRpc_stub的细节
UserServiceRpc :供给rpc服务发布者使用
在UserServiceRpc 中,相应的方法都是虚函数:
如果我们想让框架能够直接调用我们的本地方法,就需要重写UserServiceRpc 中的虚函数:
void login(::google::protobuf::RpcController* controller,
const ::taoye::LoginRequest* request,
::taoye::LoginResponse* response,
::google::protobuf::Closure* done)
{
// 框架给业务上报了请求参数 LoginRequest ,应用层获取相应数据做本地业务
std::string name = request->name();
std::string pwd = request->pwd();
//做本地业务
bool login_result = Login(name,pwd);
//把响应写入
taoye::ResultCode *code = response->mutable_result();
code->set_errcode(0);
code->set_errmsg("");
response->set_success(login_result);
//执行回调操作 ,执行响应对象数据的序列化和网络发送(该部分由框架来完成),将填充了结果的response发送回rpc框架
done->Run();
}
那么本地rpc服务提供者只需要调用框架并初始化,然会将自己的本地方法发布到rpc框架上。
在NotifyService中,我们将本地服务注册到rpc框架上,在RpcProvider类上,我们存储所有的服务,以及每个不同服务中有哪些方法。
下面我们再来看看NotifyService上需要做那些逻辑:
void RpcProvider::NotifyService(google::protobuf::Service* service)
{
ServiceInfo service_info;
// 获取服务对象的描述信息
const google::protobuf::ServiceDescriptor *pserviceDesc = service->GetDescriptor();
// 获取服务的名字
std::string service_name=pserviceDesc->name();
// 获取服务对象service的方法数量
int methodCnt = pserviceDesc->method_count();
std::cout<<"service_name:"<<service_name<<std::endl;
LOG_INFO("service_name: %s",service_name.c_str());
for(int i=0;i<methodCnt;++i)
{
//获取服务对象指定下标的服务方法的描述(抽象描述)
const google::protobuf::MethodDescriptor* pmethodeDesc = pserviceDesc->method(i);
std::string method_name = pmethodeDesc->name();
service_info.m_methodMap.insert({method_name,pmethodeDesc});
std::cout<<"method_name:"<<method_name<<std::endl;
}
service_info.m_service=service;
m_serviceMap.insert({service_name,service_info});
}
根据注册方的service*指针,我们一次得到本次注册的service_name,以及该service_name下有哪些method。并存入相应的数据结构中。
最后一步就是 启动rpc服务发布节点,run以后当前进程就处于阻塞状态,等待远程的rpc调用请求。
最后
以上就是无私纸飞机为你收集整理的RPC 框架梳理——rpc服务在rpc框架上的注册流程梳理的全部内容,希望文章能够帮你解决RPC 框架梳理——rpc服务在rpc框架上的注册流程梳理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复