概述
- RPC(Remote Procedure call)遠程過程調用。其分為兩部分:遠程過程和過程調用。遠程過程是指每臺機器上提供的服務,過程調用就是對遠程過程調用以及數(shù)據傳輸。
- RPC用通俗的語言描述:客戶端在不知道調用細節(jié)的情況下,調用存在于遠程設備上的某個對象,就像調用本地應用程序中的對象一樣。RPC比較正式的描述:一種通過傳輸介質從遠程設備程序上請求服務,而不需要了解底層傳輸介質的協(xié)議。
- 按照我對RPC的理解,我將RPC分為三層:接口層,協(xié)議層,傳輸層。
- 接口層:客戶端實現(xiàn)了服務端的接口代理,而服務端的接口為具體實現(xiàn)。
- 協(xié)議層:客戶端根據規(guī)則實現(xiàn)接口參數(shù)的打包,序列化等動作。服務端根據規(guī)則將參數(shù)反序列化,并將其傳輸?shù)椒战涌凇?/li>
- 傳輸層:傳輸介質:TCP/UDP,HTTP,藍牙,串口,USB等。
RPC流程圖RPC的特點:
- RPC是協(xié)議:它是一套協(xié)議規(guī)范,需要遵循這套規(guī)范來實現(xiàn)。目前典型的RPC實現(xiàn)包括:Dubbo,eRPC,GRPC等。目前技術的發(fā)展趨勢來看,實現(xiàn)了RPC協(xié)議的應用工具往往都會附加其他重要功能。
- 傳輸層對其透明:RPC的客戶端調用就像調用本地應用程序中的對象,所以傳輸層使用TPC/UDB、UART、USB等協(xié)議,它本省是不需要關心的。
- 協(xié)議格式對其透明:RPC客戶端調用遠程對象需要傳遞一些參數(shù),并且返回一個調用結果,至于被調用的對象內部是如何使用這些參數(shù),并計算出結果的。調用方是不需要關系的。也就傳輸?shù)膮f(xié)議格式的構成,調用方是不需要關心的。
- 跨語言能力:調用方實際是不需要關心被調用方是什么設備,使用什么語言。它可以是一個云服務器,也可以是一個小的單片機。至于這些設備使用的語言無需關心,被調用方只需要能夠解析調用方的數(shù)據及能返回正確的結果即可。
RPC的優(yōu)缺點:
-
優(yōu)點:實現(xiàn)模塊的分布式部署,可以實現(xiàn)更好的維護性,擴展性以及協(xié)同式開發(fā)。
-
缺點:①通信延遲;②地址空間隔離;③局部故障;④并發(fā)問題。
eRPC (Embedded RPC)
eRPC是什么
eRPC (Embedded RPC) is an open source Remote Procedure Call (RPC) system for multichip embedded systems and heterogeneous multicore SoCs.
eRPC(嵌入式RPC)是一種用于多芯片嵌入式系統(tǒng)和異構多核SoC的開源遠程過程調用(RPC)系統(tǒng)。
Unlike other modern RPC systems, such as the excellent Apache Thrift, eRPC distinguishes itself by being designed for tightly coupled systems, using plain C for remote functions, and having a small code size (<5kB). It is not intended for high performance distributed systems over a network.
與其他現(xiàn)代RPC系統(tǒng)(如出色的Apache Thrift)不同,eRPC的與眾不同之處在于它是為緊密耦合的系統(tǒng)設計的,使用純C實現(xiàn)遠程功能,并且代碼大小較?。?5kB)。它不適用于網絡上的高性能分布式系統(tǒng)。
eRPC源碼
eRPC源碼路徑
「https://github.com/EmbeddedRPC/erpc」
eRPC源碼目錄
我們關注兩個目錄erpc_c和erpcgen。其中:erpc_c是eRPC的C/C++實現(xiàn)。erpcgen是將IDL文件轉為C或Python源文件。
.
├──doxygen
├──erpc_c
│├──config
│├──infra
│├──port
│├──setup
│└──transports
├──erpcgen
├──erpc_python
├──erpcsniffer
├──examples
├──mk
├──README.md
├──test
└──utilities
| 目錄 | 說明 |
|---|---|
| erpc_c/config | eRPC的配置文件 |
| erpc_c/infra | eRPC的核心代碼 |
| erpc_c/port | eRPC的移植層,適配不同的開發(fā)環(huán)境 |
| erpc_c/setup | eRPC的C接口 |
| erpc_c/transports | eRPC的傳輸層,包含不同介質的驅動 |
eRPC編譯
我們需要編譯兩個東西,其中:①需要將編譯erpc_c編譯成庫,②編譯erpcgen編譯成可執(zhí)行文件,用于.erpc的IDL語法生成service和client的代碼。
編譯eRPC庫
為了方便我們編譯,我們將eRPC編程庫,然后我們的應用通過鏈接方式生成可執(zhí)行文件。步驟:
- 進入erpc_c目錄。
- 執(zhí)行 make build=release,編譯生成release版本的eRPC庫。
- 執(zhí)行 make build=release install,安裝release版本的eRPC庫。其中:默認安裝路徑是:/usr/local/lib,頭文件安裝路徑是:/usr/local/include。
編譯erpcgen
eRPC為了能過夠更加方便供開發(fā)者使用,提供了IDL的解析器erpcgen及生成規(guī)則,減少了我們編碼。erpcgen在eRPC中非常重要。步驟:
- 進入erpcgen目錄。
- 執(zhí)行 make build=release,編譯生成可執(zhí)行程序。
- 執(zhí)行 make build=release install,安裝,其中:默認安裝路徑是:/usr/local/bin。
eRPC例子
我們寫一個簡單的例子,傳輸層采用TCP,Client發(fā)一個字符串,Server端回復一個字符串。步驟:
- 新建一個目錄:youyeetoo,并新建一個eRPC的IDL文件:youyeetoo.erpc
programyouyeetoo//指定生成的文件名
interfaceyouyeetoo{//接口定義,包好一個或者多個函數(shù)
helloYouyeetoo(binarytxInput)->binary,//函數(shù):helloYouyeetoo,入參類型:binary,返回值類型:binary
}
- 將youyeetoo.erpc作為參數(shù),使用剛剛編譯的erpcgen可執(zhí)行文件,生成客戶端和服務端的代碼:
youyeetoo@youyeetoo:~/youyeetoo$erpcgen./youyeetoo.erpc
-
上述執(zhí)行完會在當前目錄下生成4個文件:"youyeetoo_client.cpp","youyeetoo_server.cpp","youyeetoo_server.h","youyeetoo.h"。其中:
- 根據.erpc文件會生成一個接口:binary_t * helloYouyeetoo(const binary_t * txInput);。
- 客戶端無需實現(xiàn)這個接口的定義,它的實現(xiàn)已經自動生成放在youyeetoo_client.cpp。上層應用直接使用即可。
- 服務端需要沒有實現(xiàn)這個接口,所以需要在上層應用實現(xiàn)函數(shù)體的內容。
-
創(chuàng)建一個客戶端的上層應用文件:client_app.cpp。其中:
- 創(chuàng)建一個TCP傳輸層通道。
- 初始化eRPC客戶端對象。
- 通過helloYouyeetoo函數(shù)進行遠程調用,發(fā)送一條消息:"hello youyeetoo!"。
- 將遠程調用的返回值打印出來。
- 編譯命令:「g++ -Wall -I. -I/usr/local/include/erpc -L/usr/local/lib youyeetoo_client.cpp client_app.cpp -lerpc -lpthread -o client_app」
- 生成client_app可執(zhí)行文件。
#include
#include
#include
#include
#include
#include"youyeetoo.h"
staticvoidfree_binary_t_struct(binary_t*data)
{
if(data->data){
erpc_free(data->data);
}
}
intmain(intargc,char*argv[])
{
erpc_transport_ttransport=erpc_transport_tcp_init("127.0.0.1",5555,false);
erpc_mbf_tmessage_buffer_factory=erpc_mbf_dynamic_init();
erpc_client_init(transport,message_buffer_factory);
char*msg="hello,youyeetoo!";
binary_tb={(uint8_t*)msg,(uint32_t)strlen(msg)};
printf("Request:%sn",msg);
binary_t*resp=helloYouyeetoo(&b);
if(resp!=NULL){
char*buf=(char*)malloc(resp->dataLength+1);
strncpy(buf,(constchar*)resp->data,resp->dataLength);
buf[resp->dataLength]='';
printf("Respond:%sn",buf);
free_binary_t_struct(resp);
free(buf);
}
erpc_transport_tcp_close();
return0;
}
- 創(chuàng)建一個服務端的上層應用文件:server_app.cpp。其中:
- 創(chuàng)建一個TCP傳輸層通道。
- 初始化eRPC服務端對象。
- 注冊服務到服務端對象中。
- 運行服務端線程。
- 當客戶端進行遠程調用時,將會進入helloYouyeetoo函數(shù),并返回。
- 編譯命令:「g++ -Wall -I. -I/usr/local/include/erpc -L/usr/local/lib youyeetoo_server.cpp server_app.cpp -lerpc -lpthread -o server_app」
- 生成client_app可執(zhí)行文件。
#include
#include
#include
#include
#include
#include
#include"youyeetoo_server.h"
binary_t*helloYouyeetoo(constbinary_t*input)
{
size_tlen=0;
char*buf;
printf("recv:%srn",input->data);
buf=(char*)malloc(strlen("hi,good!"));
memset(buf,0,strlen("hi,good!"));
strncpy(buf,"hi,good!",strlen("hi,good!"));
printf("send:hi,good!n");
len=strlen("hi,good!");
returnnewbinary_t{(uint8_t*)buf,(uint32_t)len};
}
intmain(intargc,char*argv[])
{
erpc_transport_ttransport=erpc_transport_tcp_init("127.0.0.1",5555,true);
erpc_mbf_tmessage_buffer_factory=erpc_mbf_dynamic_init();
erpc_server_tserver=erpc_server_init(transport,message_buffer_factory);
erpc_add_service_to_server(server,create_youyeetoo_service());
while(1){
erpc_server_run(server);
}
erpc_transport_tcp_close();
return0;
}
- 執(zhí)行結果:
eRPC運行結果總結
- eRPC確實是一個不錯的組件,它對底層傳輸層做了抽象,使其RPC組件不局限傳統(tǒng)的僅在TPC/UDP條件下運行。
- eRPC的傳輸層缺少可行認證,它的傳輸時明文的,對于數(shù)據來說是不安全的,應該提供安全認證的能力。
- eRPC提供IDL(接口定義語言),是我們使用起來更加方便,我們不在需要知道eRPC的具體實現(xiàn),便可以完成客戶端與服務端的調用。
歡迎關注微信公眾號『Rice嵌入式開發(fā)技術分享』
-
嵌入式
+關注
關注
5199文章
20457瀏覽量
334279
發(fā)布評論請先 登錄
如何手搓一個自定義的RPC 遠程過程調用框架
嵌入式組件的設計原則是什么?
如何將eRPC移植到rt-thread系統(tǒng)上
在eRPC上怎么添加RT-Thread系統(tǒng)接口
基于嵌入式TCP/IP的遠程GPRS控制終端的設計與實現(xiàn)
基于嵌入式Linux的遠程監(jiān)控系統(tǒng)的設計???
嵌入式RPC的設計與實現(xiàn)
如何實現(xiàn)嵌入式系統(tǒng)遠程調試
嵌入式系統(tǒng)如何進行遠程調試
RPC如何在遠程過程中調用?
嵌入式系統(tǒng)中函數(shù)如何調用
什么是遠程過程調用
嵌入式遠程過程調用組件--eRPC
評論