本节分析phxrpc怎样使用protobuf完成序列化与反序列化
phxrpc源码编译完成后,在sample目录里会生成search_main.cpp文件,里面定义了如下方法:
void Dispatch(const phxrpc::BaseRequest &req,
phxrpc::BaseResponse *const resp,
phxrpc::DispatcherArgs_t *const args) {
ServiceArgs_t *service_args{(ServiceArgs_t *)(args->service_args)};
SearchServiceImpl service(*service_args);
SearchDispatcher dispatcher(service, args);
phxrpc::BaseDispatcher<SearchDispatcher> base_dispatcher(
dispatcher, SearchDispatcher::GetURIFuncMap());
if (!base_dispatcher.Dispatch(req, resp)) {
resp->SetFake(phxrpc::BaseResponse::FakeReason::DISPATCH_ERROR);
}
}
这个方法包装了请求和结果的序列化和反序列化,同时也包装了业务处理逻辑,Dispatch方法被调用的地方在hsha_server.cpp的Worker::WorkerLogic方法中
void Worker::WorkerLogic(void *args, BaseRequest *req, int queue_wait_time_ms) {
pool_->hsha_server_stat_->inqueue_pop_requests_++;
pool_->hsha_server_stat_->inqueue_wait_time_costs_ += queue_wait_time_ms;
pool_->hsha_server_stat_->inqueue_wait_time_costs_count_++;
BaseResponse *resp{req->GenResponse()};
if (queue_wait_time_ms < MAX_QUEUE_WAIT_TIME_COST) {
HshaServerStat::TimeCost time_cost;
DispatcherArgs_t dispatcher_args(pool_->hsha_server_stat_->hsha_server_monitor_,
worker_scheduler_, pool_->args_, args);
pool_->dispatch_(*req, resp, &dispatcher_args);//这里的dispatch_就是Dispatch()方法
下面的流程图主要说明Dispatch()内部的调用流程
先明确一下,这里说的序列化是指将response变为pb二进制格式;反序列化是将request的二进制数据映射到具体类上。上面的序列化反序列化逻辑集中于SearchDispatcher的PHXEcho、Search、Notify方法里。这里以PHXEcho方法为例说明。
int SearchDispatcher::PHXEcho(const phxrpc::BaseRequest &req, phxrpc::BaseResponse *const resp) {
dispatcher_args_->server_monitor->SvrCall(-1, "PHXEcho", 1);
int ret{-1};
google::protobuf::StringValue req_pb;
google::protobuf::StringValue resp_pb;
// unpack request
{
ret = req.ToPb(&req_pb);//反序列化操作,对应下面的图1
if (0 != ret) {
phxrpc::log(LOG_ERR, "ToPb err %d", ret);
return -EINVAL;
}
}
// logic process
{
if (0 == ret) {
ret = service_.PHXEcho(req_pb, &resp_pb);//使用SearchServiceImpl的PHXEcho方法处理具体逻辑
}
}
// pack response
{
if (0 != resp->FromPb(resp_pb)) {//序列化操作,对应下面的图2
phxrpc::log(LOG_ERR, "FromPb err %d", ret);
return -ENOMEM;
}
}
phxrpc::log(LOG_DEBUG, "RETN: PHXEcho = %d", ret);
return ret;
}
上面的逻辑很简单,需要注意的一点是:
int SearchDispatcher::PHXEcho(const phxrpc::BaseRequest &req, phxrpc::BaseResponse *const resp)
入参中req的实际类型是HttpRequest,resp的实际类型是HttpResponse
至于为什么是HttpRequest类型,你可以在微信phxrpc源码分析(六)中找到想要的答案
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。