在上一篇文章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++高精度计时器——微秒级时间统计。