[实现Rpc]消息抽象层的具体实现
- IT业界
- 2025-09-02 10:39:01
![[实现Rpc]消息抽象层的具体实现](/0pic/pp_57.jpg)
目录
具象层 _ 消息抽象的实现
信息的抽象类
实现
JsonMessage
JsonRequest & JsonResponse
消息-不同消息分装实现
实现
Request
RpcRequest
TopicRequest
ServiceRequest
Response
RpcResponse
TopicResponse
ServiceResponse
实现 生产工厂
本篇文章继 BaseMessage 后继续实现,具象层架构图
具象层 _ 消息抽象的实现 信息的抽象类 JsonMessage Json的信息内容。由JsonRequest和JsonResponse继承来实现不同的功能。 实现 JsonMessage typedef std::pair<std::string,int> Address; class JsonMessage:public BaseMessage{ //继承 public: using ptr=std::shared_ptr<JsonMessage>; virtual std::string serialize() override{ //!!!!override 继承重写的强校验 std::string body; bool ret=JSON::serialize(_body,body); if(ret==false){ return std::string(); //序列化失败 } return body; } virtual bool unserialize(const std::string &msg) override{ return JSON::unserialize(msg,_body); } protected: Json::Value _body; }⭕ 前文回顾
1.over ride 继承重写的强校验
[C++#28][多态] 两个条件 | 虚函数表 | 抽象类 | override 和 final | 重载 重写 重定义
2.
继承类不能用 private,要用 protected
JsonRequest & JsonResponse //2. class JsonRequest:public JsonMessage{ public: using ptr=std::shared_ptr<JsonRequest>; }; class JsonResponse:public JsonMessage{ public: using ptr=std::shared_ptr<JsonResponse>; virtual bool check() override{ //在响应中,大部分的响应都 只有响应状态码 //only chaeck 状态码是否存在,类型 是否正确 if(_body[KEY_RCODE].isNull()==true){ ELOG("响应中 没有响应状态码!"); return false; } if(_body[KEY_RCODE].isIntegral()==false){ ELOG("响应状态码 类型错误!"); return false; } return true; } virtual RCode rcode(){ return (RCode)_body[KEY_RCODE].asInt(); //将body中的提示码 整型化 } virtual void setRCode(RCode rcode){ _body[KEY_RCODE]=(int)rcode; } };
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 class RpcRequest:public JsonRequest{ public: using ptr=std::shared_ptr<RpcRequest>; virtual bool check() override{ //重写 check 函数 //rpc 请求中,包含 请求方法名称-字符串,参数字段-对象 if(_body[KEY_METHOD].isNull()==true|| _body[KEY_METHOD].isString()==false){ ELOG("RPC请求中 没有方法名称 或者 方法名称 类型错误"); return false; } if(_body[KEY_PARAMS].isNull()==true|| _body[KEY_PARAMS].isObject()==false ){ ELOG("RPC请求中 没有 参数信息或 参数信息类型错误!"); return false; } return true; } std::string method(){ return _body[KEY_METHOD].asString(); } void setMethod(const std::string &method_name){ _body[KEY_METHOD]=method_name; } Json::Value params(){ return _body[KEY_PARAMS]; } void setParams(const Json::Value ¶ms){ _body[KEY_PARAMS]=params; } }; TopicRequest class TopicRequest : public JsonRequest { public: using ptr = std::shared_ptr<TopicRequest>; virtual bool check() override { //rpc请求中,包含请求方法名称-字符串,参数字段-对象 if (_body[KEY_TOPIC_KEY].isNull() == true || _body[KEY_TOPIC_KEY].isString() == false) { ELOG("主题请求中没有主题名称或主题名称类型错误!"); return false; } if (_body[KEY_OPTYPE].isNull() == true || _body[KEY_OPTYPE].isIntegral() == false) { ELOG("主题请求中没有操作类型或操作类型的类型错误!"); return false; } if (_body[KEY_OPTYPE].asInt() == (int)TopicOptype::TOPIC_PUBLISH && (_body[KEY_TOPIC_MSG].isNull() == true || _body[KEY_TOPIC_MSG].isString() == false)) { ELOG("主题消息发布请求中没有消息内容字段或消息内容类型错误!"); return false; } return true; } std::string topicKey() { return _body[KEY_TOPIC_KEY].asString(); } void setTopicKey(const std::string &key) { _body[KEY_TOPIC_KEY] = key; } TopicOptype optype() { return (TopicOptype)_body[KEY_OPTYPE].asInt(); } void setOptype(TopicOptype optype) { _body[KEY_OPTYPE] = (int)optype; } std::string topicMsg() { return _body[KEY_TOPIC_MSG].asString(); } void setTopicMsg(const std::string &msg) { _body[KEY_TOPIC_MSG] = msg; } }; ServiceRequest class ServiceRequest : public JsonRequest { public: using ptr = std::shared_ptr<ServiceRequest>; virtual bool check() override { //rpc请求中,包含请求方法名称-字符串,参数字段-对象 if (_body[KEY_METHOD].isNull() == true || _body[KEY_METHOD].isString() == false) { ELOG("RPC请求中没有方法名称或方法名称类型错误!"); return false; } if (_body[KEY_OPTYPE].isNull() == true || _body[KEY_OPTYPE].isIntegral() == false) { ELOG("服务请求中没有操作类型或操作类型的类型错误!"); return false; } //!!!!!!!!!! 服务发现 不需要提供主机 ip port if (_body[KEY_OPTYPE].asInt() != (int)(ServiceOptype::SERVICE_DISCOVERY) && (_body[KEY_HOST].isNull() == true || _body[KEY_HOST].isObject() == false || _body[KEY_HOST][KEY_HOST_IP].isNull() == true || _body[KEY_HOST][KEY_HOST_IP].isString() == false || _body[KEY_HOST][KEY_HOST_PORT].isNull() == true || _body[KEY_HOST][KEY_HOST_PORT].isIntegral() == false)) { ELOG("服务请求中主机地址信息错误!"); return false; } return true; } std::string method() { return _body[KEY_METHOD].asString(); } //引用传参 void setMethod(const std::string &method_name) { _body[KEY_METHOD] = method_name; } ServiceOptype optype(){ return (ServiceOptype)_body[KEY_OPTYPE].asInt(); } //枚举类型较小 前面不加&也行 void setOptype(ServiceOptype optype){ _body[KEY_OPTYPE]=(int)optype; } Address host(){ Address addr; //!!!!!!!!!!!!!!! //粗心写成 _body[KEY_HOST_IP] 报错 排查了快半小时qwq addr.first=_body[KEY_HOST][KEY_HOST_IP].asString(); addr.second=_body[KEY_HOST][KEY_HOST_PORT].asInt(); return addr; } void setHost(const Address &host){ Json::Value val; val[KEY_HOST_IP]=host.first; val[KEY_HOST_PORT]=host.second; _body[KEY_HOST]=val; } };
1.询问中的服务发现
2.
3.
⭕为什么 要 这样设计?
issues 回复:
这是向外提供的两个不i同功能的接口呀
一个是用于获取body中的数据的一个是用户设置body内容的....Response RpcResponse class RpcResponse:public JsonResponse{ public: using ptr=std::shared_ptr<RpcResponse>; virtual bool check() override{ if(_body[KEY_RCODE].isNull()==true|| _body[KEY_RCODE].isIntegral()==false ) { ELOG("响应中没有 响应状态码,或者 状态码 类型错误"); return false; } if (_body[KEY_RESULT].isNull() == true) { ELOG("响应中没有Rpc调用结果,或结果类型错误!"); return false; } return true; } Json::Value result() { return _body[KEY_RESULT]; } void setResult(const Json::Value &result) { _body[KEY_RESULT] = result; } }; TopicResponse class TopicResponse : public JsonResponse { public: using ptr = std::shared_ptr<TopicResponse>; }; ServiceResponse class ServiceResponse : public JsonResponse { public: using ptr = std::shared_ptr<ServiceResponse>; virtual bool check() override { if (_body[KEY_RCODE].isNull() == true || _body[KEY_RCODE].isIntegral() == false) { ELOG("响应中没有响应状态码,或状态码类型错误!"); return false; } if (_body[KEY_OPTYPE].isNull() == true || _body[KEY_OPTYPE].isIntegral() == false) { ELOG("响应中没有操作类型,或操作类型的类型错误!"); return false; } //!!!!!!!!!!!!!!!对服务发现部分 进行处理 if (_body[KEY_OPTYPE].asInt() == (int)(ServiceOptype::SERVICE_DISCOVERY) && (_body[KEY_METHOD].isNull() == true || _body[KEY_METHOD].isString() == false || _body[KEY_HOST].isNull() == true || _body[KEY_HOST].isArray() == false)) { ELOG("服务发现响应中响应信息字段错误!"); return false; } return true; } ServiceOptype optype() { return (ServiceOptype)_body[KEY_OPTYPE].asInt(); } void setOptype(ServiceOptype optype) { _body[KEY_OPTYPE] = (int)optype; } std::string method() { return _body[KEY_METHOD].asString(); } void setMethod(const std::string &method) { _body[KEY_METHOD] = method; } // !!!!!!!!!!!!!!!!!!!!!!!!! void setHost(std::vector<Address> addrs) { for (auto &addr : addrs) { Json::Value val; val[KEY_HOST_IP] = addr.first; val[KEY_HOST_PORT] = addr.second; _body[KEY_HOST].append(val); } } std::vector<Address> hosts() { std::vector<Address> addrs; int sz = _body[KEY_HOST].size(); for (int i = 0; i < sz; i++) { Address addr; addr.first = _body[KEY_HOST][i][KEY_HOST_IP].asString(); addr.second = _body[KEY_HOST][i][KEY_HOST_PORT].asInt(); addrs.push_back(addr); } return addrs; } };
⭕
实现 生产工厂 //实现一个消息对象的生产工厂 class MessageFactory { public: static BaseMessage::ptr create(MType mtype) { switch(mtype) { case MType::REQ_RPC : return std::make_shared<RpcRequest>(); case MType::RSP_RPC : return std::make_shared<RpcResponse>(); case MType::REQ_TOPIC : return std::make_shared<TopicRequest>(); case MType::RSP_TOPIC : return std::make_shared<TopicResponse>(); case MType::REQ_SERVICE : return std::make_shared<ServiceRequest>(); case MType::RSP_SERVICE : return std::make_shared<ServiceResponse>(); } return BaseMessage::ptr(); } template<typename T, typename ...Args> static std::shared_ptr<T> create(Args&& ...args) { return std::make_shared<T>(std::forward(args)...); } };
下一篇 将遵循 边写边测试,对上面 具象层的 消息类型代码的测试 进行整理
[实现Rpc]消息抽象层的具体实现由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“[实现Rpc]消息抽象层的具体实现”