[实现Rpc] 消息抽象层的具体实现

打印 上一主题 下一主题

主题 899|帖子 899|积分 2697

目次
具象层 _ 消息抽象的实现
信息的抽象类
实现
JsonMessage
JsonRequest & JsonResponse
消息-差别消息分装实现
实现
Request
RpcRequest
TopicRequest
ServiceRequest
Response
RpcResponse
TopicResponse
ServiceResponse
实现 生产工厂

本篇文章继 BaseMessage 后继续实现,具象层架构图

具象层 _ 消息抽象的实现

信息的抽象类


  • JsonMessage




    • Json的信息内容。
    • 由JsonRequest和JsonResponse继承来实现差别的功能。

实现

JsonMessage



  1. typedef std::pair<std::string,int> Address;
  2.     class JsonMessage:public BaseMessage{
  3.         //继承
  4.         public:
  5.         using ptr=std::shared_ptr<JsonMessage>;
  6.         virtual std::string serialize() override{
  7.             //!!!!override 继承重写的强校验
  8.             std::string body;
  9.             bool ret=JSON::serialize(_body,body);
  10.             if(ret==false){
  11.                 return std::string();
  12.                 //序列化失败
  13.             }
  14.             return body;
  15.         }
  16.         virtual bool unserialize(const std::string &msg) override{
  17.             return JSON::unserialize(msg,_body);
  18.         }
  19.         protected:
  20.             Json::Value _body;
  21.     }
复制代码
⭕ 前文回顾
   1.over ride 继承重写的强校验
  [C++#28][多态] 两个条件 | 虚函数表 | 抽象类 | override 和 final | 重载 重写 重定义

   2.
  继承类不能用 private,要用 protected

JsonRequest & JsonResponse



  1. //2.
  2.      class JsonRequest:public JsonMessage{
  3.         public:
  4.             using ptr=std::shared_ptr<JsonRequest>;
  5.      };
  6.      class JsonResponse:public JsonMessage{
  7.         public:
  8.             using ptr=std::shared_ptr<JsonResponse>;
  9.             virtual bool check() override{
  10.                 //在响应中,大部分的响应都 只有响应状态码
  11.                 //only chaeck 状态码是否存在,类型 是否正确
  12.                 if(_body[KEY_RCODE].isNull()==true){
  13.                     ELOG("响应中 没有响应状态码!");
  14.                     return false;
  15.                 }
  16.                 if(_body[KEY_RCODE].isIntegral()==false){
  17.                     ELOG("响应状态码 类型错误!");
  18.                     return false;
  19.                 }
  20.                 return true;
  21.             }
  22.             virtual RCode rcode(){
  23.                 return (RCode)_body[KEY_RCODE].asInt();
  24.                 //将body中的提示码 整型化
  25.             }
  26.             virtual void setRCode(RCode rcode){
  27.                 _body[KEY_RCODE]=(int)rcode;
  28.             }
  29.      };
复制代码
  1.通过继承 提高代码复用,去冗余
  
   2. 使用 vi 查询 json 中接口
  vi /usr/include/jsoncpp/json/value.h
esc 下/查询


可以看到上述检测接口

消息-差别消息分装实现


  • JsonRequest




    • Json的请求信息。
    • JsonRequest实现的派生类



    • RpcRequest:用于远程过程调用请求的实现。
    • TopicRequest:可能与特定主题或话题相关的请求实现。
    • ServiceRequest:针对服务请求的具体实现。


  • JsonResponse




    • Json的回复信息。
    • JsonResponse实现的派生类



    • RpcResponse:对应于远程过程调用响应的实现。
    • TopicResponse:与特定主题或话题相关响应的实现。
    • ServiceResponse:服务于具体服务响应的实现。


实现

Request



RpcRequest

  1. class RpcRequest:public JsonRequest{
  2.     public:
  3.         using ptr=std::shared_ptr<RpcRequest>;
  4.         virtual bool check() override{
  5.             //重写 check 函数
  6.             //rpc 请求中,包含 请求方法名称-字符串,参数字段-对象
  7.             if(_body[KEY_METHOD].isNull()==true||
  8.             _body[KEY_METHOD].isString()==false){
  9.                 ELOG("RPC请求中 没有方法名称 或者 方法名称 类型错误");
  10.                 return false;
  11.             }
  12.             if(_body[KEY_PARAMS].isNull()==true||
  13.             _body[KEY_PARAMS].isObject()==false
  14.             ){
  15.                 ELOG("RPC请求中 没有 参数信息或 参数信息类型错误!");
  16.                 return false;
  17.             }
  18.             return true;
  19.         }
  20.         std::string method(){
  21.             return _body[KEY_METHOD].asString();
  22.         }
  23.         void setMethod(const std::string &method_name){
  24.             _body[KEY_METHOD]=method_name;
  25.         }
  26.         Json::Value params(){
  27.             return _body[KEY_PARAMS];
  28.         }
  29.         void setParams(const Json::Value &params){
  30.             _body[KEY_PARAMS]=params;
  31.         }
  32. };
复制代码
TopicRequest

  1.     class TopicRequest : public JsonRequest {
  2.         public:
  3.             using ptr = std::shared_ptr<TopicRequest>;
  4.             virtual bool check() override {
  5.                 //rpc请求中,包含请求方法名称-字符串,参数字段-对象
  6.                 if (_body[KEY_TOPIC_KEY].isNull() == true ||
  7.                     _body[KEY_TOPIC_KEY].isString() == false) {
  8.                     ELOG("主题请求中没有主题名称或主题名称类型错误!");
  9.                     return false;
  10.                 }
  11.                 if (_body[KEY_OPTYPE].isNull() == true ||
  12.                     _body[KEY_OPTYPE].isIntegral() == false) {
  13.                     ELOG("主题请求中没有操作类型或操作类型的类型错误!");
  14.                     return false;
  15.                 }
  16.                 if (_body[KEY_OPTYPE].asInt() == (int)TopicOptype::TOPIC_PUBLISH &&
  17.                     (_body[KEY_TOPIC_MSG].isNull() == true ||
  18.                     _body[KEY_TOPIC_MSG].isString() == false)) {
  19.                     ELOG("主题消息发布请求中没有消息内容字段或消息内容类型错误!");
  20.                     return false;
  21.                 }
  22.                 return true;
  23.             }
  24.             
  25.             std::string topicKey() {
  26.                 return _body[KEY_TOPIC_KEY].asString();
  27.             }
  28.             void setTopicKey(const std::string &key) {
  29.                 _body[KEY_TOPIC_KEY] = key;
  30.             }
  31.             TopicOptype optype() {
  32.                 return (TopicOptype)_body[KEY_OPTYPE].asInt();
  33.             }
  34.             void setOptype(TopicOptype optype) {
  35.                 _body[KEY_OPTYPE] = (int)optype;
  36.             }
  37.             std::string topicMsg() {
  38.                 return _body[KEY_TOPIC_MSG].asString();
  39.             }
  40.             void setTopicMsg(const std::string &msg) {
  41.                 _body[KEY_TOPIC_MSG] = msg;
  42.             }
  43.     };
复制代码
ServiceRequest

  1. class ServiceRequest : public JsonRequest {
  2.         public:
  3.             using ptr = std::shared_ptr<ServiceRequest>;
  4.             virtual bool check() override {
  5.                 //rpc请求中,包含请求方法名称-字符串,参数字段-对象
  6.                 if (_body[KEY_METHOD].isNull() == true ||
  7.                     _body[KEY_METHOD].isString() == false) {
  8.                     ELOG("RPC请求中没有方法名称或方法名称类型错误!");
  9.                     return false;
  10.                 }
  11.                 if (_body[KEY_OPTYPE].isNull() == true ||
  12.                     _body[KEY_OPTYPE].isIntegral() == false) {
  13.                     ELOG("服务请求中没有操作类型或操作类型的类型错误!");
  14.                     return false;
  15.                 }
  16.         //!!!!!!!!!! 服务发现  不需要提供主机 ip port
  17.                 if (_body[KEY_OPTYPE].asInt() != (int)(ServiceOptype::SERVICE_DISCOVERY) &&
  18.                     (_body[KEY_HOST].isNull() == true ||
  19.                     _body[KEY_HOST].isObject() == false ||
  20.                     _body[KEY_HOST][KEY_HOST_IP].isNull() == true ||
  21.                     _body[KEY_HOST][KEY_HOST_IP].isString() == false ||
  22.                     _body[KEY_HOST][KEY_HOST_PORT].isNull() == true ||
  23.                     _body[KEY_HOST][KEY_HOST_PORT].isIntegral() == false)) {
  24.                     ELOG("服务请求中主机地址信息错误!");
  25.                     return false;
  26.                 }
  27.                 return true;
  28.             }
  29.             std::string method() {
  30.                 return _body[KEY_METHOD].asString();
  31.             }
  32.             //引用传参
  33.             void setMethod(const std::string &method_name) {
  34.                 _body[KEY_METHOD] = method_name;
  35.             }
  36.             ServiceOptype optype(){
  37.                 return (ServiceOptype)_body[KEY_OPTYPE].asInt();
  38.             }
  39. //枚举类型较小 前面不加&也行
  40.             void setOptype(ServiceOptype optype){
  41.                 _body[KEY_OPTYPE]=(int)optype;
  42.             }
  43.             Address host(){
  44.                 Address addr;
  45.     //!!!!!!!!!!!!!!!
  46.     //粗心写成 _body[KEY_HOST_IP] 报错 排查了快半小时qwq      
  47.                 addr.first=_body[KEY_HOST][KEY_HOST_IP].asString();
  48.                 addr.second=_body[KEY_HOST][KEY_HOST_PORT].asInt();
  49.                 return addr;
  50.             }
  51.             void setHost(const Address &host){
  52.                 Json::Value val;
  53.                 val[KEY_HOST_IP]=host.first;
  54.                 val[KEY_HOST_PORT]=host.second;
  55.                 _body[KEY_HOST]=val;
  56.             }
  57.     };
复制代码
1.询问中的服务发现



2.



3.




   ⭕为什么 要 这样设计?
  

issues 回复:
这是向外提供的两个不i同功能的接口呀


  • 一个是用于获取body中的数据的
  • 一个是用户设置body内容的....

Response



RpcResponse

  1. class RpcResponse:public JsonResponse{
  2.     public:
  3.         using ptr=std::shared_ptr<RpcResponse>;
  4.         virtual bool check() override{
  5.             if(_body[KEY_RCODE].isNull()==true||
  6.                _body[KEY_RCODE].isIntegral()==false )
  7.             {
  8.                 ELOG("响应中没有 响应状态码,或者 状态码 类型错误");
  9.                 return false;
  10.             }
  11.            if (_body[KEY_RESULT].isNull() == true) {
  12.                     ELOG("响应中没有Rpc调用结果,或结果类型错误!");
  13.                     return false;
  14.                 }
  15.                 return true;
  16.             }
  17.             Json::Value result() {
  18.                 return _body[KEY_RESULT];
  19.             }
  20.             void setResult(const Json::Value &result) {
  21.                 _body[KEY_RESULT] = result;
  22.             }
  23.     };
复制代码
TopicResponse

  1. class TopicResponse : public JsonResponse {
  2.         public:
  3.             using ptr = std::shared_ptr<TopicResponse>;
  4.     };
复制代码
ServiceResponse



  1. class ServiceResponse : public JsonResponse {
  2.         public:
  3.             using ptr = std::shared_ptr<ServiceResponse>;
  4.             virtual bool check() override {
  5.                 if (_body[KEY_RCODE].isNull() == true ||
  6.                     _body[KEY_RCODE].isIntegral() == false) {
  7.                     ELOG("响应中没有响应状态码,或状态码类型错误!");
  8.                     return false;
  9.                 }
  10.                 if (_body[KEY_OPTYPE].isNull() == true ||
  11.                     _body[KEY_OPTYPE].isIntegral() == false) {
  12.                     ELOG("响应中没有操作类型,或操作类型的类型错误!");
  13.                     return false;
  14.                 }
  15. //!!!!!!!!!!!!!!!对服务发现部分 进行处理
  16.                 if (_body[KEY_OPTYPE].asInt() == (int)(ServiceOptype::SERVICE_DISCOVERY) &&
  17.                    (_body[KEY_METHOD].isNull() == true ||
  18.                     _body[KEY_METHOD].isString() == false ||
  19.                     _body[KEY_HOST].isNull() == true ||
  20.                     _body[KEY_HOST].isArray() == false)) {
  21.                     ELOG("服务发现响应中响应信息字段错误!");
  22.                     return false;
  23.                 }
  24.                 return true;
  25.             }
  26.             ServiceOptype optype() {
  27.                 return (ServiceOptype)_body[KEY_OPTYPE].asInt();
  28.             }
  29.             void setOptype(ServiceOptype optype) {
  30.                 _body[KEY_OPTYPE] = (int)optype;
  31.             }
  32.             std::string method() {
  33.                 return _body[KEY_METHOD].asString();
  34.             }
  35.             void setMethod(const std::string &method) {
  36.                 _body[KEY_METHOD] = method;
  37.             }
  38. // !!!!!!!!!!!!!!!!!!!!!!!!!
  39.             void setHost(std::vector<Address> addrs) {
  40.                 for (auto &addr : addrs) {
  41.                     Json::Value val;
  42.                     val[KEY_HOST_IP] = addr.first;
  43.                     val[KEY_HOST_PORT] = addr.second;
  44.                     _body[KEY_HOST].append(val);
  45.                 }
  46.             }
  47.             std::vector<Address> hosts() {
  48.                 std::vector<Address> addrs;
  49.                 int sz = _body[KEY_HOST].size();
  50.                 for (int i = 0; i < sz; i++) {
  51.                     Address addr;
  52.                     addr.first = _body[KEY_HOST][i][KEY_HOST_IP].asString();
  53.                     addr.second = _body[KEY_HOST][i][KEY_HOST_PORT].asInt();
  54.                     addrs.push_back(addr);
  55.                 }
  56.                 return addrs;
  57.             }
  58.     };
复制代码




实现 生产工厂

  1. //实现一个消息对象的生产工厂
  2.     class MessageFactory {
  3.         public:
  4.             static BaseMessage::ptr create(MType mtype) {
  5.                 switch(mtype) {
  6.                     case MType::REQ_RPC : return std::make_shared<RpcRequest>();
  7.                     case MType::RSP_RPC : return std::make_shared<RpcResponse>();
  8.                     case MType::REQ_TOPIC : return std::make_shared<TopicRequest>();
  9.                     case MType::RSP_TOPIC : return std::make_shared<TopicResponse>();
  10.                     case MType::REQ_SERVICE : return std::make_shared<ServiceRequest>();
  11.                     case MType::RSP_SERVICE : return std::make_shared<ServiceResponse>();
  12.                 }
  13.                 return BaseMessage::ptr();
  14.             }
  15.             
  16.             template<typename T, typename ...Args>
  17.             static std::shared_ptr<T> create(Args&& ...args) {
  18.                 return std::make_shared<T>(std::forward(args)...);
  19.             }
  20.     };
复制代码
下一篇 将遵循 边写边测试,对上面 具象层的 消息类型代码的测试 进行整理

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表