开源项目之C++远程方法调用框架 RMI for C++

RMI for C++ 是一个专为 C++ 语言提供的远程方法调用框架,与 CORBA 不同的是,CORBA 适合不同的编程语言之间进行互操作,而 RMI for C++ 专为 C++ 涉及,因此效率更高,速度更快,开发也便捷。工程如图:

工程需要用到第三方库boost(已放到源码包中),Boost库是一个经过千锤百炼、可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一。 Boost库由C++标准委员会库工作组成员发起,在C++社区中影响甚大,其成员已近2000人。 Boost库为我们带来了最新、最酷、最实用的技术,是不折不扣的“准”标准库。

程序是使用CORBA规范调用C++程序,在源码中直接使用预处理器指定接口以及封装进程参数,当然需要使用Boost库序列化本地C++程序框架。

echo服务器 实例源码:

#include <RCF/RCF.hpp> 


RCF_BEGIN(I_Echo, "I_Echo")
  RCF_METHOD_R1(std::string, echo, const std::string &);
RCF_END(I_Echo);

class Echo
{
public:
  std::string echo(const std::string &msg) { return msg; }
};

int main()
{
  int port = 50001;
  RCF::RcfServer server(port);
  server.bind<I_Echo, Echo>();
  server.start();
  return 0;
}

echo客户端 实例源码:

#include <RCF/RCF.hpp>


RCF_BEGIN(I_Echo, "I_Echo")
  RCF_METHOD_R1(std::string, echo, const std::string &);
RCF_END(I_Echo);

int main()
{
  std::cout << RcfClient<I_Echo>("localhost", 
                               50001).echo("my message");
  return 0;
}
Boost.Serialization库,用于序列化的参数和返回值。它具有标准的类型和容器自动进行,很容易扩展到用户定义的类。它也使我们能够序列化指针,多态指针和妥善处理单个对象的多个指针。

基本用法

使用这个框架有三个基本步骤:

  1. 使用RCF_xxx宏来定义接口。
  2. 使用的的暴露RcfServer类实现该接口的对象。
  3. 使用RcfClient <>类公开的对象的服务器上调用方法。

接口定义宏的使用方法如下:

RCF_BEGIN( type, type_id )
  // ...

  RCF_METHOD_xx( return_type, name, ....):
  // ...

RCF_END( type )

type是为接口的标识符,TYPE_ID是一个字符串,给出一个运行时的接口的描述。

一旦我们定义了一个接口使用RCF_xxx宏,我们就可以启动服务器,并绑定到具体对象的接口:

{
  // create the server and tell it which port to listen on

  RCF::RcfServer server(port);

  // Interface is the identifer of the interface we're exporting,

  // Object is a type that implements that interface

    
  // one object for each client

  server.bind<Interface, Object>(); 

  // ... or one object shared by all clients

  Object object;
  server.bind<Interface>(object); 

  // tell the server to start listening for connections

  server.start();

  // ...


  // the server will shut down automatically as it goes out of scope

}
该对象是静态绑定到相应的接口,也没有必要为对象从一个接口类派生的情况一样,为传统的动态多态性。取而代之的是,编译器在编译的时候,这不仅是更有效的解决了接口,但也允许更灵活的语义。
服务器可以同时处理多个客户端,即使在单线程模式下,并且可以在任何时候停止。服务器所公开的对象的生命周期来确定当前连接到给定的对象的数目,一旦有没有更多的活的对象的连接,超时被设置,并当它过期时,该对象被删除。
为了使客户端调用,我们实例化相应的RcfClient <>模板,并通过服务器的IP地址和端口号的构造函数。当第一个远程方法调用,客户端,然后尝试连接到服务器,给定对象的查询,调用远程对象的请求的成员函数,然后返回远程的返回值。

// define the interface

RCF_BEGIN(Interface, "Interface")
  RCF_METHOD_R2(int, add, int, int);
RCF_END(Interface);

// ...


{
  std::string ip = "localhost";
  int port = 50001;
  RcfClient<Interface> client(ip, port);
  
  // connect and call the add function

  int sum = client.add(1,1);
  
  // connection closed as we exit scope

}

如果出现任何异常,在服务器端调用请求的对象时,一个异常的类型RCF ​​:: RemoteException的传播回客户端和抛出。如果出现任何异常,在其他地方,例如在服务器端,而序列化的参数,那么服务器将强行关闭连接时,客户端会抛出一个异常。

RCF自动处理的参数类型,包括int、 double、std::string、STL容器、指针、引用、boost::shared_ptr、std::auto_ptr等等。
在CORBA中,标记的参数中有in、 out、inout,根据它们把参数进行封送处理。按照以下约定:

Value: in
Pointer: in
Const reference: in
Nonconst reference: inout

Nonconst reference to pointer: out

要使用用户定义的类型作为参数或返回值,需要一些额外的序列化代码(Boost.Serialization),如下。

struct MyStruct
{
  int a;
  int b;
  int c;
  double d;
  std::string s;
  std::map <std::string, std::vector<std::string> > m;
  
  template<typename Archive>
  void serialize(Archive &archive, unsigned int version)
  {
    ar & a & b & c & d & s & m;
  }
  
};

RCF_BEGIN(MyInterface, "MyInterface")
  RCF_METHOD_R1(MyStruct, myfunc, const MyStruct &);
RCF_END(MyInterface);


学习的目的是成熟!~

源码下载(含boost库)




你可能感兴趣的:(C++,框架,String,object,服务器,interface)