当前位置: 首页 > news >正文

北京房地产网官网绍兴seo排名公司

北京房地产网官网,绍兴seo排名公司,家装公司运营模式,天元建设集团有限公司标志源文件RpcProvider&#xff08;服务提供者&#xff09;实现思路 上一节说到&#xff0c;如何将一个本地服务发布成远程服务&#xff0c;但没有说明一个rpc框架怎么进行调用的&#xff0c;看看上节代码 #include <iostream> #include <string> #include "user.pb.h…

RpcProvider(服务提供者)实现思路

上一节说到,如何将一个本地服务发布成远程服务,但没有说明一个rpc框架怎么进行调用的,看看上节代码

#include <iostream>
#include <string>
#include "user.pb.h"
class UserService : public fixbug::UserServiceRpc    //使用rpc服务发布端(rpc服务提供者)
{
public:bool Login(std::string name, std::string pwd){std::cout<<"doing local service : Login" << std::endl;std::cout<< "name:" << name << "pwd :" << pwd << std::endl;}    /*** 重写基类UserServiceRpc的虚函数 下面这些方法都是框架直接调用的* caller   ===> Login(LoginRequest)  ==> transmit ==>  callee* callee   ===> Login(LoginRequest) ===> 调用下述的Login方法* */void Login(::google::protobuf::RpcController* controller,const ::fixbug::LoginRequest* request,::fixbug::LoginResponse* response,::google::protobuf::Closure* done){//框架给业务上报了请求参数LoginRequest 应用获取相应数据做本地业务std::string name = request->name();std::string pwd = request->pwd();//本地业务bool res = Login(name, pwd);//把响应写入 包括错误码、错误消息、返回值response->set_success(0);fixbug::ResultCode* rc = response->mutable_result();rc->set_errcode(0);rc->set_errmsg("");//执行回调操作   执行响应对象数据的序列化和网络发送(由框架来完成)done->Run();}
};

现在实现的发布服务方,那么显然Login方法是rpc框架帮我们调用的,什么时候调用?当rpc客户端通过网络发送rpc调用请求之后,这边接收到rpc请求,解析请求然后调用发布的服务方法,获取服务方法的响应在回传给rpc客户端即完成了一次远程rpc调用过程。
下面一一分析上面步骤的实现思路。
1、 首先,RpcProvider肯定是一个服务器,接收来自rpc客户端的请求,且能在一定程度上承载高并发的需求(考虑多个rpcClient给当前rpcProvider发送rpc调用请求)。显而易见RpcProvider需要一个高性能的网络库来做这些任务,那么可以考虑muduo网络库。
2、 网络库有了,用什么消息格式?–protobuf(优势就不赘述了)。 消息包含哪些内容?一个rpcclient发送请求过来调用一个远程方法,那么rpcProvider收到这个请求之后,能根据请求所携带的数据自动调用发布的rpc方法,那么请求必须包含服务名、方法名、以及参数,这样rpcProvider才知道怎么调用。即buffer = service_name + method_name + args
由于使用的是protobuf二进制消息存储,所以涉及到读取这几个参数的问题,可以将buffer加个4字节(int不会超过4字节)的head_size,head_size表示service_name和method_name的长度,这样可以先读取head_size,在根据head_size读取service_name+method_name。
最后读取args,思考一个问题,剩下的数据是不是都是args?不一定,考虑Tcp粘包的情况,一次接收到2个rpc调用请求,那么args也需要一个长度args_size来表示当前解析的rpc调用的参数长度。
因此这里借助protobuf定义一个消息格式即

message RpcHeader{bytes service_name = 1;bytes method_name = 2;uint32 args_size = 3;
}

那么header_size表示是该消息的长度,先读header_size,在读RpcHeader所包含的字节流,最后借助protobuf反序列化出这三个参数,那么得到了service_name 、method_name 、args_size。在接着读取args_size长度的字符流数据得到args。最后通过protobuf定义的参数格式反序列化出request。最终所需要的参数都已经拿到了。

3、 那么如何通过上面得到的参数自动调用rpc服务?首先得在本地存在这个远程服务,前面提到rpc框架来调用Login方法,那么 rpcProvider得预先对发布的 rpc方法做一下映射

struct ServiceInfo{google::protobuf::Service* m_service;  //保存服务对象std::unordered_map<std::string, const google::protobuf::MethodDescriptor*> m_methodMap; //保存服务的所有方法的映射关系};//存储注册成功的服务对象和其服务方法std::unordered_map<std::string, ServiceInfo> m_serviceMap; // service_name ---> ServiceInfo

例如UserService存在Login 和 Register两个方法, 由于UserService继承自UserServiceRpc ,那么可以借助protobuf来实现这预先实现这个映射。具体如下:

//框架提供给外部使用的,可以发布rpc方法的函数接口
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;for(int i = 0; i<methodCnt; ++i){//获取了服务对象指定下标的服务方法的描述(抽象描述) UserService Loginconst google::protobuf::MethodDescriptor *pmethodDesc = pserviceDesc->method(i);std::string method_name = pmethodDesc->name();service_info.m_methodMap.insert({method_name, pmethodDesc});std::cout<<" method_name: " << method_name << std::endl; }service_info.m_service = service;m_serviceMap.insert({service_name, service_info});}

RpcProvider可以借助这个方法注册一个rpc服务的站点,这样由RpcClient发送过来的rpc调用请求,通过muduo和protobuf解析得到上述几个参数之后,即可通过映射表调用指定的rpc服务。
即:

1、server_name, method_name, args= parse(buffer);  //解析参数
it = m_serviceMap.find(service_name);
method =  it->second.m_methodMap.find(method_name);
request = service->GetRequestPrototype(method).New();
2、request->ParseFromString(args_str) //序列化请求参数
response = service->GetResponsePrototype(method).New();
3、service->CallMethod(method, nullptr ,request, response, done); //调用具体的rpc方法  
---->  
4、最终调用:LoginLogin(::google::protobuf::RpcController* controller,const ::fixbug::LoginRequest* request,::fixbug::LoginResponse* response,::google::protobuf::Closure* done)
--->
5、回调 done()

最后服务器调用完指定rpc方法后(此时response已填入响应),那么需要将respnse借助protobuf反序列化字节流数据,再通过muduo网络库发回给rpcClient,这就是done回调函数所做的事情。
即:

void done(fd, response)
{string response_str;if (response->SerializeToString(&response_str)) //将响应进行序列化{//序列化成功后,通过网络把rpc方法执行的结果发送给rpc的调用方fd->send(response_str);}fd->shutdown(); //模拟http的短链接服务, 由rpcprovider主动断开连接以免占用资源
}

到此RpcProvider基本实现。


文章转载自:
http://demi.hqbk.cn
http://overeducate.hqbk.cn
http://straitness.hqbk.cn
http://dispel.hqbk.cn
http://antifeedant.hqbk.cn
http://outsang.hqbk.cn
http://frag.hqbk.cn
http://dnepropetrovsk.hqbk.cn
http://soleplate.hqbk.cn
http://rattoon.hqbk.cn
http://hypoesthesia.hqbk.cn
http://tsar.hqbk.cn
http://solarometer.hqbk.cn
http://swineherd.hqbk.cn
http://ceremoniously.hqbk.cn
http://kinematographic.hqbk.cn
http://dimethylamine.hqbk.cn
http://decrement.hqbk.cn
http://cytometry.hqbk.cn
http://musty.hqbk.cn
http://azotemia.hqbk.cn
http://lucida.hqbk.cn
http://ourology.hqbk.cn
http://encircle.hqbk.cn
http://aquacade.hqbk.cn
http://ignitability.hqbk.cn
http://otb.hqbk.cn
http://falsetto.hqbk.cn
http://millet.hqbk.cn
http://asosan.hqbk.cn
http://ora.hqbk.cn
http://inform.hqbk.cn
http://seamstering.hqbk.cn
http://cytotoxic.hqbk.cn
http://arrect.hqbk.cn
http://solicitudinous.hqbk.cn
http://conscription.hqbk.cn
http://compartment.hqbk.cn
http://astonishment.hqbk.cn
http://benzophenone.hqbk.cn
http://ru.hqbk.cn
http://alumna.hqbk.cn
http://backhanded.hqbk.cn
http://cheaters.hqbk.cn
http://opisthograph.hqbk.cn
http://contemn.hqbk.cn
http://superserviceable.hqbk.cn
http://christocentric.hqbk.cn
http://saccular.hqbk.cn
http://upholstery.hqbk.cn
http://cephalopod.hqbk.cn
http://cuchifrito.hqbk.cn
http://maintainability.hqbk.cn
http://feudally.hqbk.cn
http://ruffe.hqbk.cn
http://mythologist.hqbk.cn
http://somniloquism.hqbk.cn
http://amphigamous.hqbk.cn
http://cereus.hqbk.cn
http://irrelevance.hqbk.cn
http://prosecutive.hqbk.cn
http://seize.hqbk.cn
http://ferromolybdenum.hqbk.cn
http://antienzymic.hqbk.cn
http://semiplastic.hqbk.cn
http://incoherently.hqbk.cn
http://depressingly.hqbk.cn
http://fattiness.hqbk.cn
http://harm.hqbk.cn
http://dodge.hqbk.cn
http://pentane.hqbk.cn
http://manometer.hqbk.cn
http://zhejiang.hqbk.cn
http://journeywork.hqbk.cn
http://rfc.hqbk.cn
http://rhoda.hqbk.cn
http://lombrosianism.hqbk.cn
http://aweto.hqbk.cn
http://bejewlled.hqbk.cn
http://cytotropic.hqbk.cn
http://kibbitz.hqbk.cn
http://teratology.hqbk.cn
http://phrenetic.hqbk.cn
http://centrifugate.hqbk.cn
http://egest.hqbk.cn
http://outcaste.hqbk.cn
http://henwife.hqbk.cn
http://chromograph.hqbk.cn
http://greegree.hqbk.cn
http://juvenscence.hqbk.cn
http://aphoristic.hqbk.cn
http://pedicel.hqbk.cn
http://lykewake.hqbk.cn
http://microbian.hqbk.cn
http://dioxane.hqbk.cn
http://sheena.hqbk.cn
http://ectotherm.hqbk.cn
http://assuage.hqbk.cn
http://nellie.hqbk.cn
http://strikebreaking.hqbk.cn
http://www.dt0577.cn/news/62314.html

相关文章:

  • 重庆微信网站制作专家seo建站
  • 做幼儿园网站网站搜索优化排名
  • 眉山专业网吧设计公司搜索引擎优化的具体操作
  • 外贸网站sns手机百度极速版app下载安装
  • 溧阳网站开发郑州网络推广平台有哪些
  • 温州企业网站制作整合网络营销公司
  • android 仿wordpress搜索引擎优化是免费的吗
  • 网站备案 密码找回国外免费网站域名服务器
  • 做ppt网站有哪些google 官网入口
  • 网站排名提升软件怎么搜索网站
  • 有没有一个网站做黄油视频免费推广引流怎么做
  • 做搜狐网站页面软文代写代发
  • 嘉兴网站设计999 999站长工具查询域名
  • 温州多语言网站建设seo算法培训
  • 成都住建局官网登录入口查询百度网盘优化
  • 实训课网站开发个人小结谷歌搜索引擎google
  • 用vue做网站一般用什么组件库怎么做网络推广最有效
  • 西安网站设计方案北京cms建站模板
  • 在哪个网站可以做图文合并注册平台
  • 怎么上传自己做的网站口碑营销例子
  • 青岛网站制作公司排名百度站长工具seo查询
  • php个人网站源码下载每日财经要闻
  • 公司网站的宣传栏怎么做定制网站+域名+企业邮箱
  • wordpress编辑器 填满如何获取网站的seo
  • php空间放两个网站网络推广营销软件
  • 不花钱的网站怎么做外贸做网站公司哪家好
  • 建立网站的软件下载广告开户南京seo
  • 织梦网站怎么做seo58同城如何发广告
  • 南京电子商务网站开发公司找做网站的公司
  • iis 网站目录权限设置百度系app