在上一篇文章RPC通信框架——RCF介紹中,介紹了RCF的優點,本篇文章從頭開始演示如何用RCF編寫一個跨進程通信的Demo程序。
將RCF編譯為靜態庫
從官網下載到的源碼中包含一個RCF的項目,但是這項目是用來編譯動態庫的。可以參考這個項目來進行靜態庫的設置。
首先創建一個空的項目文件,然后設置編譯為靜態庫,添加源文件RCF.cpp,只需要這一個文件就夠了,因為,這個文件里面,包含了其他所有的源文件。這種源代碼的引用方式,編譯為動態庫,還可以接受,但是編譯為靜態庫就會有一些問題,后面的文章中再討論,不影響Demo的演示。
然后添加預處理器:
WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0500
禁用特定警告(不是必須的):
4275 4251 4510 4511 4512 4127 4702
添加附加依賴項:
ws2_32.lib
這樣就可以編譯靜態庫了。
Client、Server項目配置
Client、Server的項目配置,首先是非常常見的引用RCF靜態庫的路徑等配置,需要注意的一點就是需要添加如下預處理器:
WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0500
編寫接口定義
項目配置好后,需要添加Client、Server通信的功能,而他們通信是基於事先定義好的接口的,定義如下:
#pragma once #include "rcf/rcf.hpp" #include <windows.h> #include <iostream> #include <string> using namespace std; RCF_BEGIN(I_HELLO, "I_HELLO") RCF_METHOD_V1(void, SayHello, const string&) RCF_METHOD_R1(int, add, int&) RCF_METHOD_V0(void, test) RCF_END(I_HELLO)
編寫接口的Server實現
接口的定義是用來規定通信支持的功能,以及通信的協議。有了這些規定后,就需要來實現具體的功能,並且這是屬於Server端的實現,Client端無需知道這些實現的細節,代碼如下:
#pragma once #include "rcf/rcf.hpp" #include <windows.h> #include <iostream> #include <string> using namespace std; #include "hello.h" class HelloImpl { public: void SayHello(const string& world) { cout << "hello " << world << endl; } int add(int& a) { a = a + a; return a + 2; } void test() {} };
編寫Server服務
那么接下來,需要編寫一個控制台或者Windows服務來承載此Server服務,這里就選擇簡單的控制台程序。
RCF在Windows下支持三種通信協議:TCP、UDP、命名管道,
此處我們選擇TCP:
#include "stdafx.h" #include "hello.h" int _tmain(int argc, _TCHAR* argv[]) { RCF::RcfInitDeinit rcf_init; HelloImpl hello; RCF::RcfServer server(RCF::TcpEndpoint(50001)); server.bind<I_HELLO>(hello); server.start(); while(true) { Sleep(1000); } return 0; }
如代碼所示,在程序入口,需要通過RcfInitDeinit類的構造函數,進行RCF相關的初始化,程序退出時,通過RcfInitDeinit的析構函數進行RCF的清理工作。
RCF初始化后,通過RcfServer的bind方法,綁定接口對應的具體實現,然后通過start方法啟動服務。
編寫Client程序
Client程序,在調用RCF相關方法之前,也需要通過RcfInitDeinit進行初始化工作,代碼如下:
#include "stdafx.h" #include "hello.h" #include "stop_watch.h" int _tmain(int argc, _TCHAR* argv[]) { RCF::RcfInitDeinit rcf_init; RcfClient<I_HELLO> client(RCF::TcpEndpoint(50001)); string str = "test"; client.SayHello(str); int a = 3; int b = client.add(a); cout << "a = " << a << ", b = " << b << endl; stop_watch watch; watch.start(); for (int i = 0; i < 20000; ++i) { client.test(); } watch.stop(); cout << watch.elapsed_ms() << " ms" << endl; return 0; }
簡單性能測試
在我的筆記本 Windows7 專業版 SP1 x64 、Intel(R) Core(TM) i5-2450M CPU @ 2.5GHz、 12G內存 的機器上,通過此Demo,對RCF進行了測試。
調用兩萬次,耗時1647ms左右,平均每秒可以調用12143次,平均每次調用耗時82微妙。
計時工具——stop_watch
計時工具 stop_watch類,可以參考C++高精度計時器——微秒級時間統計。