1. 资源准备:
下载boost库:http://sourceforge.net/projects/boost/files/boost/1.53.0/
下载RCF1.O: http://download.youkuaiyun.com/download/javacmm2012/5465473
2. 配置工程目录:
把下载后的RCF和Boost库添加到自己项目的附加包含目录中,如下图所示:
3. 编写代码:
(1)先定义交互接口,这个接口头文件在客户端和服务端都要引用,在接口文件中,可以定义结构体等等。注意,所有指定的结构体都要实现串行化,不然不能在网络上正确传输。方法的定义是通过一系列宏定义实现的,如
RCF_METHOD_V1,RCF_METHOD_V2。。。具体可参见RMI_Exercise4\RCF-1.0\include\RCF\Idl.hpp定义,代码可参见:
#ifndef Communication_H_
#define Communication_H_
#include <string>
#include <vector>
#include <RCF/Idl.hpp>
#include <SF/vector.hpp>
struct sUser
{
//用户结构体
int _id; //用户id,唯一值,逐渐递增
std::string _userName; //用户名
std::string _password; //密码
template<typename Archive>
void serialize( Archive &ar, unsigned int version )
{
ar & _id & _userName & _password;
}
};
struct sDateTime
{
//时间日期类型合法格式:2012.12.12 12:12:12
short _iYear;
short _iMonth;
short _iDay;
short _iHour;
short _iMinute;
short _iSecond;
template<typename Archive>
void serialize( Archive & ar, unsigned int version )
{
ar & _iYear & _iMonth & _iDay & _iHour &_iMinute & _iSecond;
}
};
struct sMeeting
{
int _id; // 会议Id,唯一值
sDateTime _sStart; // 会议开始日期
sDateTime _sEnd; // 会议结束日期
std::string _strTitle; // 会议的主题
std::vector<sUser> _vecUser;// 会议所有成员,只要与会成员中的一个想删除会议,就会删除成功
template<typename Archive>
void serialize( Archive & ar, unsigned int version )
{
ar & _id & _sStart & _sEnd & _strTitle &_vecUser;
}
};
RCF_BEGIN(MyService, "MyService")
//获取所有的会议
RCF_METHOD_V1(void, getAllMeeting,std::vector<sMeeting>&);
//获取所有的用户
RCF_METHOD_V1(void, getAllUser,std::vector<sUser>&);
//添加一个议程
RCF_METHOD_V4(void, addMeeting,std::string,std::string,sMeeting,bool&);
//登陆接口,成功返回true,失败返回false
RCF_METHOD_V3(void, loginIn,std::string,std::string,bool&);
//注册用户接口,注册成功放回true, 失败返回false
RCF_METHOD_V3(void, registerUser,std::string,std::string,bool&);
//查询用户当前的会议
RCF_METHOD_V4(void, queryMeeting,std::string,std::string,std::vector<sMeeting>&,bool&);
//删除指定会议
RCF_METHOD_V4(void, deleteMeeting,std::string,std::string,int,bool&);
//删除所有会议
RCF_METHOD_V3(void, deleteAllMeeting,std::string,std::string,bool&);
RCF_END(MyService);
#endif ///< Communication_H_
(2)
编写服务端代码:先定义一个用来实现接口类中所有方法的代理类,类中必须包含接口中定义的所有方法的实现。代码可参见:
#ifndef MyServiceImpl_H_
#define MyServiceImpl_H_
#include <fstream>
#include "../IDL/Communication.h"
class CMyServiceImpl
{
public:
void getAllMeeting( std::vector<sMeeting>& vecMeetign);
void getAllUser( std::vector<sUser>& vecUser);
void loginIn(std::string username,std::string password,bool& bResult);
void registerUser( std::string username,std::string password,bool& bResult);
void queryMeeting(std::string username,std::string password,std::vector<sMeeting>& vecMeeting,bool& bResult);
void deleteMeeting(std::string username,std::string password,int meetingId,bool& bResult);
void deleteAllMeeting(std::string username,std::string password,bool& bResult);
void addMeeting(std::string username,std::string password,sMeeting meeting,bool& bResult);
public:
CMyServiceImpl(); //构造函数,读取配置文件
~CMyServiceImpl(); //析构函数,将内容写入到配置文件中去
private:
std::vector<sUser> m_vecUser; //用户列表
std::vector<sMeeting> m_vecMeeting; //所有的会议列表
};
#endif ///<MyServiceImpl_H_
编写这个类以后,我们就把这个类绑定到我们的服务上去,参见如下代码:
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <RCF/RcfServer.hpp>
#include <RCF/TcpEndpoint.hpp>
#include "MyServiceImpl.h"
int main()
{
CMyServiceImpl myServiceImpl;
RCF::RcfServer server(RCF::TcpEndpoint("0.0.0.0", 50001));//指定绑定的Ip和端口号
server.bind<MyService>(myServiceImpl);//MyService是IDL中定义的服务名
server.start();
server.waitForStopEvent();
return 0;
}
注意:在服务端和客户端的工程中都要包含RCF.cpp, 这时RCF库中的一个文件,不然可能会出现链接错误。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <iomanip>
#include <sstream>
#include "../IDL/Communication.h"
#include <RCF/TcpEndpoint.hpp>
using namespace std;
int main()
{
try
{
RcfClient<MyService> client(RCF::TcpEndpoint("127.0.0.1", 50001));//指定服务器的Ip和端口号
string username,userpassword;
bool bIsAdmin = false;
bool bLoginIn = false;
bool bResult = false;
//直接调用接口中的方法,就可以啦
client.registerUser(tempusername,temppassword,bResult);
//sMeeting meeting;
//client.addMeeting(username,userpassword,meeting,bResult);
//client.deleteMeeting(username,userpassword,meetingId,bResult);
//client.deleteAllMeeting(username,userpassword,bResult);
}
catch(const std::exception &e)
{
cout << "Caught exception:\n";
cout << "Type: " << typeid(e).name() << "\n";
cout << "What: " << e.what() << "\n";
}
return 0;
}
注意:有可能编译不过,这时候看下错误提示,到底是什么没有定义,在我的电脑上,需定义以下宏定义,才能使编译通过,如图: