Server
? RpcServer:rpc功能模塊與?絡通信部分結合RpcServer分為兩部分 1.提供函數調用服務的服務端 2.提供服務注冊的客戶端
對內提供好rpc服務的路由關系管理map<method,服務描述對象>,以及rpc請求消息的分發處理函數。給Dispatcher提供onRpcRequest rpc請求的回調函數,根據請求中的method(),從map中找到對應的服務描述對象 進行參數檢查,無誤調用函數處理 最后向服務端返回應答。
右側serviceRegister(method, service) 是服務端本地注冊接口,用于將某個 method(方法名)與其對應的 service(服務描述對象)進行綁定,注冊到本地的 RpcRouter 中,便于后續接收到 RPC 請求時進行路由調用對應的函數服務。
但僅僅本地知道能提供哪些服務還不夠,如果希望其他客戶端也能發現這些服務并遠程調用,就必須通過 RegistryClient注冊客戶端 將服務信息(method 與 host 地址)注冊到服務注冊中心 RegistryServer。
? RegistryServer:服務發現注冊功能模塊與?絡通信部分結合
對內提供好服務提供者和服務發現者的數據管理 。給Dispatcher提供服務操作請求的分發處理函數onServiceRequest,分為服務發現/服務注冊。
服務發現:返回能提供該method函數的主機地址列表
服務注冊:將提供者信息管理起來
PDManager分為服務提供者管理,服務發現者管理。1.進行服務注冊? 提供者管理要add新增提供者 發現者管理要給訂閱該method方法的發現者進行服務上線通知ontifyOffline。2.進行服務發現 發現者管理add新增發現者 并返回method方法提供者列表(提供者管理)應答。?
onShutdown服務提供者或者發現者斷開連接時的回調函數,1.提供者斷開連接 發現者管理發送服務下線通知ontifyOffline? 提供者管理del刪除該提供者的管理? 2.發現者斷開 不需要通知 發現者管理del刪除該發現者的管理
? TopicServer:發布訂閱功能模塊與?絡通信部分結合對內完成主題map<key,topic>和訂閱者信息map<conn,subscriber>的管理。topic包含主題名稱+當前主題的訂閱者列表vector<sub>,sub包含訂閱者conn+訂閱的主題列表名稱vector<string>.
給Dispatcher回調函數onTopicRequest處理主題操作的請求,1.主題創建2.主題刪除3.訂閱主題4.取消訂閱5.向主題發布消息
雙向映射管理:一方面維護“主題 → 訂閱者”,另一方面維護“訂閱者 → 主題”
1.訂閱主題 訂閱者sub中新增主題 被訂閱的主題topic對象中訂閱者列表也要新增訂閱者
2.取消訂閱 同理訂閱者刪除了主題 主題對象中也要刪除訂閱者
3.刪除主題 map<key,topic>刪除映射,訂閱該主題的訂閱者中也要刪除該主題
4.連接斷開的回調函數onShutdown 處理訂閱者斷開連接, map<conn,sub>刪除映射 訂閱者訂閱的所以主題中刪除該訂閱者
服務端總體邏輯
服務端總體有3個回調函數注冊到Dispatcher中,onRpcRequest 處理rpc請求的 onServiceRequest處理服務請求 onTopicRequest處理主題操作請求的
Client
將以上模塊進?整合就可以實現各個功能的客?端了。
? RegistryClient:服務注冊功能模塊與?絡通信客?端結合
服務注冊客戶端 提供一個服務注冊的接口registryMethod 通過requestor進行發送服務注冊請求并等待應答。給Dis注冊的回調函數onResponse是Requestor模塊的接收應答的回調函數,畢竟請求由Requestor發送 也由它設置回調函數接收并處理。
? DiscoveryClient:服務發現功能模塊與?絡通信客?端結合
服務發現客戶端 對內提供處理服務端主動推送的服務上線/下線通知請求的分發接口,對外提供服務發現接口,設置服務下線的處理回調(當作成員函數 構造時傳入 刪除連接池中的該服務的長連接)
所以給Dispatcher的回調函數有兩個,1onResponse客戶端主動發送服務發現請求的應答回調 2.onServiceRequest處理服務端主動推送的服務上線/下線通知請求的回調(服務下線時調用_offline_callback刪除長連接)。
? RpcClient:DiscoveryClient & RPC功能模塊與?絡通信客?端結合這個RpcClient也是分為兩部分 1.提供rpc調用的客戶端 2.提供服務發現的服務發現客戶端
對外提供3個call函數,1.同步2.異步future3.異步回調,但內部是套用Requestor的3個send函數進行調用的。其中同步call是調用的同步send(內部套用異步send+外部等待) 23異步future和異步回調call都是調用的回調send,2異步future是在回調函數中設置的set_value(bind捕獲為了延長promise的生命周期)
call進行rpc調用前我們必須要找到能提供服務的服務端地址,怎么知道?向注冊中心進行服務發現,這就需要服務端發現客戶端 進行服務發現。向外提供1.服務發現接口2.服務上線/下線的回調函數? ? ? ? ? ? ? ? ? ?
? TopicClient:發布訂閱功能模塊與?絡通信客?端結合發布訂閱客戶端,對內提供主題消息推送的消息分發處理回調函數onpublish(根據本地map<key,cb>調用對應主題的回調函數 訂閱主題時候傳入的),對外提供主題操作的函數1.主題創建2.主題刪除3.訂閱主題4.取消訂閱5.主題消息發布
這里給Dispathcer傳入的回調函數也是兩個,1.onResponse客戶端主動發送服務發現請求的應答回調 2.onPublish 服務端主動發送的主題消息 進行分發調用對應的回調函數。
客戶端總體邏輯圖
dispatcher中存入有三個回調函數,1.客戶端主動requestor()發送請求,自然由它的回調函數onResponse進行處理 2.服務端主動發送的消息 主題消息的發布,對訂閱該主題的客戶端發送消息,對于被動接收到的主題消息 topic客戶端自己設置回調函數onPublish給dispatcher模塊。3.服務端主動發送的消息 服務上線/下線通知 registry客戶端設置回調函數onServiceRequest給disoatcher模塊
服務端抽象層
主 Reactor 負責監聽 listenfd 上的新連接請求,一旦有連接到來就通過 accept() 建立連接,獲取客戶端的套接字 connfd。(并封裝為 BaseConnection 對象)
從 Reactor 則負責監聽所有客戶端套接字的 IO 事件(如可讀)。當客戶端發來數據,服務端就通過對應的 connfd 從內核讀取數據,先寫入 BaseBuffer 輸入緩沖區。
然后上層 Protocol 模塊從緩沖區中讀取數據,處理粘包拆包,將原始字節數據反序列化為 BaseMessage 對象,最終由 Dispatcher 根據 msg->type() 派發到注冊的業務處理回調函數中去。
客戶端連接建立時 會調用服務端外部提供的2個set接口,onClose onConn,而onMessage回調是Dispatcher設置的 onMessage把messgae傳給Dis讓它按消息類型派發數據
(Dispatcher 里的回調函數是由各個業務模塊在初始化階段,通過 registerHandler(msgType, 回調函數) 主動注冊進去的)
客戶端抽象層
客戶端的 Reactor 維護了一條與服務端的連接,監聽這個套接字 獲取服務端返回的應答和主題服務上下線推送/主題消息發布廣播,并通過 Dispatcher 根據消息類型調用對應的回調函數。
給外部提供了5個接口,1.connect()建立客戶端到服務端的 TCP 連接 2.shutdown()主動關閉當前連接 3.setCloseCallback()關閉連接回調函數 4.setConnectionCallback()連接建立成功回調函數 5.send()發送請求
oMessage也是由dis提供 對應類型的回調函數由各模塊初始化時傳入
具象層
針對不同的請求,從BaseMessage中派?出不同的請求和響應類型,以便于在針對指定消息處理時,能夠更加輕松的獲取或設置請求及響應中的各項數據元素。
BaseMessage最基礎的消息結構體:消息id 消息類型mtype(epc topic service)
JsonMessage繼承BaseMessage:新增body字段 存儲請求/響應的內容
JsonMessage子類可以分為 請求和響應,因為如果是響應類的話 需要有響應碼 check()檢查響應是否正確。
1.JsonRequest 請求消息的基類 無新增字段
? ? ? ? 1.RpcRequset 新增 1.method調用的函數名 2.parameters 參數(json格式 參數名:類型)
? ? ? ? 2.TopicRequset 1.key主題名 2.optype主題操作類型(創建/刪除/訂閱/取消訂閱/主題發布) 3.(msg)如果是主題發布 就有這個字段 主題發布的內容
? ? ? ? 3.ServiceRequset 1.method函數名 2.optype服務操作類型(注冊/發現/上線/下線)
3.host 告訴服務端自己的地址 (僅在注冊、上線時需要)
2.JsonResponse 應答消息的基類 重寫chekc() 如子類需要根據自己結構判斷可再進行重寫
? ? ? ? 1.RpcResponse 1.rcode返回碼 2.result 結果數據
? ? ? ? 2.TopicResponse 1.rcode返回碼 主題的操作應答只需要返回是否完成就可以
? ? ? ? 3.ServiceResponse?
? ? ? ? ? ? ? ? 注冊/上線/下線操作:1.rcode返回碼 2.optype服務操作類型
? ? ? ? ? ? ? ? 發現操作:1.rcode 2.optype 3.method要發現的函數 4.hosts能提供method方法的主機地址列表
業務層
業務層就是基于底層的通信框架,針對項?中具體的業務功能的實現了,?如Rpc請求的處理,發布訂閱請求的處理以及服務注冊與發現的處理等等。
1.rpc請求處理
1.Client模塊:對外提供call()接口,給用戶進行rpc調用。內部通過Requestor發送rpc請求。
Requestor提供onResponse給Dispatcher模塊 處理Requestor發送請求返回的應答。
2.中間傳輸層模塊:通過底層網絡通信NetWork發送數據,Dispatcher模塊根據消息類型的不同調用對應的回調函數處理。
3.Server模塊:對內完成method->函數的映射管理,并提供onRpcRequest給Dispatcher模塊 處理rpc請求消息的回調函數,調用對應的rpc函數 并返回應答。
2.發布訂閱請求的處理
1.Client模塊:PSManager對外提供5個接口,這些請求都是通過Requestor()進行發送,因此Requestor要給Dis提供onResponse回調處理 這些請求對應的響應。除此之外,PSManager還要給Dis提供onPublish函數,處理主題消息,因為這是服務端主動發送的 并不是Requestor發送請求返回的響應,所以單獨處理。
2.Network 負責客戶端與服務端之間的底層連接及消息收發? Dispatcher消息派發
3.Server模塊:PSManger給Dis提供onTopicRequest 處理topic主題消息調用對應函數完成主題創建/刪除/... 并發送操作是否完成的應答。? 如果是主題發布,服務端還需要主動給訂閱該主題的客戶端進行廣播,通過Publish函數send發送消息。
3.服務注冊&發現
1.Client模塊:PDManager模塊分為兩部份 1.Provider服務提供者 對外提供服務注冊serviceRegistry() 通過Requestor發送服務注冊請求。2.Discoverer服務發現者 對外提供服務發現serviceDiscovery() 也是通過Requestor發送服務發現請求。除此之外,還要給Dis提供onServiceRequest來處理服務端主動發送的 服務上線/下線消息的回調處理函數。
2.
3.Server模塊:PDManager給Dis提供一個統一的接口onServiceRequest來處理客戶端發來的服務注冊/服務發現請求,1.服務注冊 Pro新增提供者 Discover進行服務上線通知 返回注冊成功應答? ? ? ? 2.服務發現 Discover新增發現者 返回發現成功應答包含服務提供者地址
因此服務發現者 需要有服務上線/下線通知的函數 onlineNotify/offlineNotify,服務端給客戶端主動發送消息。
整體設計框架
整個項目的實現分為三層,抽象層 具象層 業務層。
抽象層 將底層的網絡通信機制(BaseServer BaseClient Basebuffer BaseConnection都是封裝的Muduo庫) 應用層通信協議(自己實現的LVProtocol) 請求響應的數據結構進行統一的封裝抽象(BaseMessgae 派生出對應的子類),還有個回調函數MessageCallback 將原始字節流轉化為message對象時觸發 給Dispatcher進行派發。
具象層 底層網絡通信借助Muduo庫? 通信協議自己實現的LV通信協議? 請求響應的數據結構根據三個模塊派生對應的子類
業務層 三個模塊各自提供處理對應請求的回調函數給Dispatcher模塊。
Dispatcher模塊MType對應的回調函數
請求類都是由對應的服務端提供回調函數1.rpc服務端 onRpcRequest 2.服務注冊/發現服務端onServiceRequest 3.主題服務端onTopicRequest
響應類由Requestor提供的onResponse處理
主題消息發布topic客戶端提供的publish 服務上下線通知服務客戶端的onServiceRequest
功能場景 | 消息類型(MType) | 說明 |
---|---|---|
RPC 請求 | MType::REQ_RPC | 客戶端發起 RPC 函數調用請求 |
RPC 響應 | MType::RSP_RPC | 服務端返回 RPC 執行結果 |
Topic 請求 | MType::REQ_TOPIC | 客戶端執行主題相關操作(訂閱、發布等) |
Topic 響應 | MType::RSP_TOPIC | 服務端返回主題請求處理結果 |
服務請求 | MType::REQ_SERVICE | 客戶端請求服務注冊/發現/上下線等操作 |
服務響應 | MType::RSP_SERVICE | 服務端對服務請求的響應 |