天天看點

eRPC:通過實作雙向請求的串行通訊傳輸(dual serial transport)支援client/server混合運作Dual serial transport

Dual serial transport

概述

eRPC 的預設的設計模型是簡單的主從模式,也就是裝置A上運作服務,另一個裝置B主動發起請求調用A的服務,但在實際的應用中,我們需要雙向的請求,也就是說裝置A,裝置B互為主從,兩台裝置上都會運作服務供對方調用。在這種模式下,原有的串行通訊傳輸(SerialTransport)實作就不能滿足要求,因為裝置接收到的資料無法知道是給server的請求(Requst),還是給client的響應(Response)。

如果要實作上述的雙向請求并不複雜,隻要修改串行通訊傳輸(SerialTransport)的實作,在發送資料時,多發送一個資料類型的标志,這樣接收方收到資料時先判斷這個标志,如果是給server端的Request,後續的資料就讓server接收,如果是給client端的Response,就讓client接收。

由此就可以實作一個支援雙向請求的串行資料傳輸(dual serial transport).通過隻修改傳輸層,就可以讓eRPC架構實作client/server混合運作。

實作邏輯

如下圖是Dual serial transport的實作模型。

因為client/server混合運作時,client和server都會發送資料也都會接收資料,是以關鍵的問題就是通過資料類型标志(segType),讓接收到的資料被正确的接收端(client或server)接收。

eRPC:通過實作雙向請求的串行通訊傳輸(dual serial transport)支援client/server混合運作Dual serial transport

資料發送

為了防止client/server的資料發送能同時正常執行,設計了一個發送資料互斥鎖(send_lock),使用互斥鎖将client和server發送資料的操作嚴格區分開。

在發送正式資料之前先發送一個資料類型标志(segType)标志

資料接收

為了確定client/server能正确收到自己應該接收的資料,設計了三個資料接收信号量:

變量名 說明 備注
server_semaphore server 端資料接收信号量 初始狀态下server端接收請求資料時被此信号量阻塞,等待被開關線程收喚醒
client_semaphore client 端資料接收信号量 初始狀态下cliennt端接收響應資料時被此信号量阻塞,等待被開關線程收喚醒
switch_semaphore 資料開關線程 資料接收信号量 開關線程負責讀取資料類型标志(segType),并根據标志喚醒server或client接收資料

當資料開關線程喚醒server或client接收資料後,自己就進入阻塞狀态,等待server或client端的喚醒

當server或client被被開關線程收喚醒接收完資料後,會設定switch_semaphore信号量喚醒開關線程準備接收下一個資料類型标志(segType)

上述三個資料接收信号量和發送資料互斥鎖定義在

erpc_setup_dual_serial.cpp

資料開關線程的實作在:

DualSerialTransport::serverThread

在原有的SerialTransport的資料發送函數基礎上,DualSerialTransport 做了簡單修改,增加了信号量等待和發送資料類型标志(segType)動作,參見:

DualSerialTransport::underlyingSend

在原有的SerialTransport的資料接收函數基礎上,DualSerialTransport 增加了信号量等待動作,參見:

DualSerialTransport::underlyingReceive

測試驗證

關于雙向資料傳輸完整的測試代碼參見

https://gitee.com/l0km/facelog/blob/dev3/facelog-client-cpp/dependencies/erpc/test/erpc_dual_test.cpp