前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信phxrpc源码分析(五)-protobuf集成流程

微信phxrpc源码分析(五)-protobuf集成流程

原创
作者头像
路小饭
修改2019-03-14 09:20:40
1K0
修改2019-03-14 09:20:40
举报

本节分析phxrpc怎样使用protobuf完成序列化与反序列化

1 调用流程

phxrpc源码编译完成后,在sample目录里会生成search_main.cpp文件,里面定义了如下方法:

代码语言:javascript
复制
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方法中

代码语言:javascript
复制
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()内部的调用流程

  • 客户需要在SearchServiceImpl中实现自己的业务处理逻辑
  • BaseDispathcer类的Dispatch方法是入口
  • Dispatch请求req中带有url,使用SearchDispatcher的GetURIFuncMap方法可以根据url确认调用的具体方法(PHXEcho、Search、Notify)
  • SearchDispatcher的PHXEcho调用了SearchServiceImpl中的PHXEcho实现具体业务逻辑

2 序列化与反序列化

先明确一下,这里说的序列化是指将response变为pb二进制格式;反序列化是将request的二进制数据映射到具体类上。上面的序列化反序列化逻辑集中于SearchDispatcher的PHXEcho、Search、Notify方法里。这里以PHXEcho方法为例说明。

代码语言:javascript
复制
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;
}

上面的逻辑很简单,需要注意的一点是:

代码语言:javascript
复制
int SearchDispatcher::PHXEcho(const phxrpc::BaseRequest &req, phxrpc::BaseResponse *const resp)

入参中req的实际类型是HttpRequest,resp的实际类型是HttpResponse

至于为什么是HttpRequest类型,你可以在微信phxrpc源码分析(六)中找到想要的答案

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 调用流程
  • 2 序列化与反序列化
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档