[實現Rpc] 消息抽象層的具體實現

目錄

具象層 _ 消息抽象的實現

信息的抽象類

實現

JsonMessage

JsonRequest & JsonResponse

消息-不同消息分裝實現

實現

Request

RpcRequest

TopicRequest

ServiceRequest

Response

RpcResponse

TopicResponse

ServiceResponse

實現 生產工廠


本篇文章繼 BaseMessage 后繼續實現,具象層架構圖

具象層 _ 消息抽象的實現

信息的抽象類
  1. JsonMessage
    • Json的信息內容。
    • JsonRequestJsonResponse繼承來實現不同的功能。

實現

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 下/查詢

可以看到上述檢測接口


消息-不同消息分裝實現

  1. JsonRequest
    • Json的請求信息。
    • JsonRequest實現的派生類
    1. RpcRequest:用于遠程過程調用請求的實現。
    2. TopicRequest:可能與特定主題或話題相關的請求實現。
    3. ServiceRequest:針對服務請求的具體實現。
  1. JsonResponse
    • Json的回復信息。
    • JsonResponse實現的派生類
    1. RpcResponse:對應于遠程過程調用響應的實現。
    2. TopicResponse:與特定主題或話題相關響應的實現。
    3. 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 &params){_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 portif (_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)...);}};

下一篇 將遵循 邊寫邊測試,對上面 具象層的 消息類型代碼的測試 進行整理

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/70133.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70133.shtml
英文地址,請注明出處:http://en.pswp.cn/web/70133.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機考研之數據結構:深入解析最大公約數與歐幾里得算法

一、生活中的公約數應用 在日常生活中&#xff0c;經常需要處理"均分分配"問題。例如&#xff1a;要將24塊巧克力和18塊餅干平均分給小朋友&#xff0c;最多能分給幾個小朋友&#xff1f;這就是典型的求最大公約數問題。 二、基本概念詳解 約數與公約數 約數&…

NCHAR_CS和CHAR_CS,導致UNION ALL 時,提示SQL 錯誤 [12704] [72000]: ORA-12704: 字符集不匹配

檢查涉及的數據表和列的字符集設置 -- 查詢表的字符集 SELECT parameter, value FROM nls_database_parameters WHERE parameter LIKE NLS_CHARACTERSET;-- 查詢列的字符集&#xff08;對于特定表&#xff09; SELECT column_name, character_set_name FROM all_tab_columns W…

算法之 跳躍游戲

文章目錄 55.跳躍游戲思路參考&#xff1a;56.合并區間 55.跳躍游戲 55.跳躍游戲 靈神思路 思路分析&#xff1a; 兩種思路&#xff0c;思路1是我們可以直接維護當前到達i的時候所能到達的最右的邊界mr&#xff0c;如果i>mr就說明無法到達i,否則就是可以到達&#xff1b;…

在C#中動態訪問對象屬性時,用表達式樹可以獲得高效性能

在C#中如何用表達式樹動態訪問對象屬性的問題。用戶可能已經知道反射的基本用法&#xff0c;但想用表達式樹來提高性能&#xff0c;因為表達式樹編譯后的委托執行速度比反射快。 首先&#xff0c;表達式樹的基本概念。表達式樹允許在運行時構建代碼&#xff0c;并編譯成可執行的…

深入解析 Flutter 性能優化:從原理到實踐

深入解析 Flutter 性能優化&#xff1a;從原理到實踐的全面指南 Flutter 是一個高性能的跨平臺框架&#xff0c;但在開發復雜應用時&#xff0c;性能問題仍然可能出現。性能優化是開發高質量 Flutter 應用的關鍵。本篇博客將從 Flutter 的渲染原理出發&#xff0c;結合實際場景…

使用 Python 爬蟲獲取微店快遞費用 item_fee API 接口數據

在電商運營中&#xff0c;快遞費用是影響商家利潤和用戶體驗的重要因素之一。微店作為國內知名的電商平臺&#xff0c;提供了豐富的 API 接口供開發者使用&#xff0c;其中也包括查詢商品快遞費用的接口。通過調用微店的 item_fee 接口&#xff0c;開發者可以獲取指定商品的快遞…

MySQL基本操作——包含增刪查改(環境為Ubuntu20.04,MySQL5.7.42)

1.庫的操作 1.1 創建數據庫 語法&#xff1a; 說明&#xff1a; 大寫的表示關鍵字 [] 是可選項 CHARACTER SET: 指定數據庫采用的字符集 COLLATE: 指定數據庫字符集的校驗規則 1.2 創建案例 創建一個使用utf8字符集的db1數據庫 create database db1 charsetutf8; …

Spring Boot 定時任務:輕松實現任務自動化

在現代應用開發中&#xff0c;定時任務是一個常見的需求。比如&#xff0c;我們可能需要定時清理過期數據、定時發送郵件通知等。 操作流程 開啟定時任務注解 在啟動類添加注解EnableScheduling 設置時間&#xff08;固定時間間隔&#xff09; 使用 Scheduled 注解創建定時…

七星棋牌全開源修復版源碼解析:6端兼容,200種玩法全面支持

本篇文章將詳細講解 七星棋牌修復版源碼 的 技術架構、功能實現、二次開發思路、搭建教程 等內容&#xff0c;助您快速掌握該棋牌系統的開發技巧。 1. 七星棋牌源碼概述 七星棋牌修復版源碼是一款高度自由的 開源棋牌項目&#xff0c;該版本修復了原版中的多個 系統漏洞&#…

【Rust中級教程】1.12. 生命周期(進階) Pt.2:生命周期變型、協變、不變、逆變

喜歡的話別忘了點贊、收藏加關注哦&#xff08;加關注即可閱讀全文&#xff09;&#xff0c;對接下來的教程有興趣的可以關注專欄。謝謝喵&#xff01;(&#xff65;ω&#xff65;) 這篇文章在Rust初級教程的基礎上對生命周期這一概念進行了補充&#xff0c;建議先看【Rust自…

Vue 項目登錄的基本流程

Vue 用戶登錄的基本流程包括以下6個步驟&#xff1a; 步驟&#xff1a; 1. 創建登錄表單 在前端&#xff0c;首先要創建一個登錄表單&#xff0c;用戶輸入賬號&#xff08;用戶名、郵箱、手機號等&#xff09;和密碼。 示例&#xff1a;Login.vue <template><div…

【算法】回溯算法

回溯算法 什么是回溯 人生無時不在選擇。在選擇的路口&#xff0c;你該如何抉擇 ..... 回溯&#xff1a; 是一種選優搜索法&#xff0c;又稱為試探法&#xff0c;按選優條件向前搜索&#xff0c;以達到目標。但當探索到某一步時&#xff0c;發現原先選擇并不優或達不到目標&am…

SpringAI系列 - RAG篇(三) - ETL

目錄 一、引言二、組件說明三、集成示例一、引言 接下來我們介紹ETL框架,該框架對應我們之前提到的階段1:ETL,主要負責知識的提取和管理。ETL 框架是檢索增強生成(RAG)數據處理的核心,其將原始數據源轉換為結構化向量并進行存儲,確保數據以最佳格式供 AI 模型檢索。 …

2025 docker可視化管理面板DPanel的安裝

1.什么是 DPanel &#xff1f; DPanel 是一款 Docker 可視化管理面板&#xff0c;旨在簡化 Docker 容器、鏡像和文件的管理。它提供了一系列功能&#xff0c;使用戶能夠更輕松地管理和部署 Docker 環境。 軟件特點&#xff1a; 可視化管理&#xff1a;提供直觀的用戶界面&#…

基于Python的深度學習音樂推薦系統(有配套論文)

音樂推薦系統 提供實時音樂推薦功能&#xff0c;根據用戶行為和偏好動態調整推薦內容 Python、Django、深度學習、卷積神經網絡 、算法 數據庫&#xff1a;MySQL 系統包含角色&#xff1a;管理員、用戶 管理員功能&#xff1a;用戶管理、系統設置、音樂管理、音樂推薦管理、系…

微信小程序---計劃時鐘設計與實現

微信小程序-計劃時鐘已上線,歡迎各位小伙伴的測試和使用~(微信小程序搜計劃時鐘即可使用) 在這篇博客中,我們將探討如何在微信小程序中設計和實現一個任務管理功能,該功能允許用戶添加、刪除和查看任務。任務管理系統的核心是基于日期和時間的任務管理,可以設置任務的開…

RPA-實例(UiPath )

UiPath 是一個流行的機器人流程自動化(RPA)工具,用于自動化重復性任務。以下是一個簡單的實例,展示如何使用 UiPath 自動化一個常見的任務:從 Excel 文件中讀取數據并將其輸入到網頁表單中。 實例:從 Excel 讀取數據并自動填寫網頁表單 步驟 1:準備工作 安裝 UiPath S…

華為固態電池引發的思索

華為固態電池真牛&#xff01; 超長續航&#xff1a;單次充電即可行駛3000公里 極速充電&#xff1a;五分鐘內充滿80% 極致安全&#xff1a;不可燃、不漏液 長壽命設計&#xff1a;循環壽命達10000次以上 如上是華為電池展示的優勢項&#xff0c;每一條都讓我們心動不已。…

算法分析—— 《歸并排序》

《排序數組》 題目描述&#xff1a; 給你一個整數數組 nums&#xff0c;請你將該數組升序排列。 你必須在 不使用任何內置函數 的情況下解決問題&#xff0c;時間復雜度為 O(nlog(n))&#xff0c;并且空間復雜度盡可能小。 示例 1&#xff1a; 輸入&#xff1a;nums [5,2…

UEFI Spec 學習筆記---11 - Protocols — UEFI Driver Model(1)

11.UEFI Driver Model 遵循 UEFI model 的 EFI driver 是不允許去遍歷所有的 controller 來識別需要安裝到哪個 controller 上的&#xff0c;而是通過 EFI_BOOT_SERVICES 的 ConnectController 和調用 Binding Driver 來實現&#xff1b; 具體實現如下&#xff1a; CoreConne…