【问题标题】:C++ Calling methods of a remote object (RPC alike)远程对象的 C++ 调用方法(类似 RPC)
【发布时间】:2012-05-10 12:52:26
【问题描述】:

我正在寻找一个 RPC 库,它允许我在另一个进程(在 Windows 上)中调用对象的成员函数。

我目前遇到的问题是一些服务器端对象已经存在并且有多个实例。服务器应该能够将指针/标识符传递给客户端,客户端实现代理,然后将调用定向到远程对象实例。所以我基本上想要的是这样的:

Client:
TestProxy test = RemoteTestManager.GetTestById(123);
test.echo("bla");

其中 Test 的实例已经存在于服务器上,并且 RemoteTestManager 是客户端在另一个 rpc 调用中获得的服务器上的管理器类。此外,它最好在命名管道上运行,因为同一台机器上可以有多个服务器(实际上我想要更像一个简单的 IPC:D)。

所以我的问题实际上是:C++ 是否有类似的东西,还是我必须自己编写代码

【问题讨论】:

    标签: c++ windows ipc pipe rpc


    【解决方案1】:

    就跨网络的低级序列化消息而言,Protocol Buffers 是一种常见的选择...

    http://code.google.com/p/protobuf/

    如需更完整的 RPC 堆栈,请查看 Apache Thrift...

    http://thrift.apache.org/

    【讨论】:

      【解决方案2】:

      COM 怎么样?似乎完全符合您的要求。

      【讨论】:

      • 好吧,但我不想为所有内容编写包装类。并且由于我无法更改要导出的对象的定义,因此无法使用 COM
      【解决方案3】:

      您可能已经找到了解决方案。仅供参考,我创建了一个与您在此处询问的内容相匹配的库。看看CppRemote 库。该库具有以下与您的描述相匹配的功能:

      • 通过名称(std::string)获取指向服务器对象的指针。
      • 在服务器上绑定现有对象(非侵入式),然后从客户端获取该对象的代理。
      • 服务器可以绑定到多个现有对象的实例。
      • 它已命名管道传输。
      • 轻巧易用。

      服务器代码

      Test test1, test2;
      remote::server svr;
      svr.bind<itest>(&test1, "test1");
      svr.bind<itest>(&test2, "test2");
      svr.start(remote::make_basic_binding<text_serializer, named_pipe_transport>("pid"));
      ...
      

      客户端代码

      remote::session client;
      client.start(remote::make_basic_binding<text_serializer, named_pipe_transport>("pid"));
      
      auto test1 = client.get<itest>("test1");
      auto test2 = client.get<itest>("test2");
      test1->echo("bla");
      test2->echo("bla");
      

      【讨论】:

        【解决方案4】:

        ZeroMQ 可能是目前最好的 IPC 系统,它允许客户端/服务器拓扑的多种组合。而且它也非常快速高效。

        如何访问服务器对象取决于它们是如何实现的,CORBA 有这个功能,但我现在不会尝试使用 CORBA(或者后来是 TBH)。许多 RPC 系统允许您根据需要创建对象,或连接到单个实例。连接到为您创建并在该会话期间为每次调用保留的对象(即为每个客户端创建并保持活动的对象)仍然相当普遍。对象池也相当常见。但是,您必须管理这些服务器对象的生命周期,我无法给出真正的建议,因为您还没有说明您的对象是如何管理的。

        我怀疑你想要命名管道,坚持使用 tcp/ip 连接 - 连接到 localhost 是一个非常轻量级的操作(COM 在此配置中实际上是零开销)。

        【讨论】:

        • 嗯,tcp/ip 连接的问题是我的服务器需要监听一个端口,而每个端口只能有一个服务器监听。对于命名管道,如果我要使用套接字,我可以只使用服务器的 pid 作为标识符,我需要某种方法来获取我想要侦听的服务器的套接字。好吧,这些对象实际上并没有真正由服务器本身管理,而是由另一个导入服务器以授予 rpc 访问其他程序的应用程序管理,所以我不能像 RFC 那样拥有任何垃圾收集。
        【解决方案5】:

        名单上有候选人。但这取决于问题空间。快速浏览一下,Capnproto,作者 kenton varda,也许是合适的。 CORBA 有点老,但在许多系统和框架中使用,例如 ACE。问题之一是在 capnproto PassByReference 和 PassByConstruction 中也提供了能力引用的 PassByCopy。 COM系统也有一些问题需要自己讨论。 ZeroMQ 真的很酷,我曾经感冒过。而且它不支持 RPC,这意味着您必须在零级消息传递上实现它。如果您不是在寻找诸如功能安全性、promise pipelining 和 capnproto 提供的其他不错的功能等功能,那么 Google protobuf、kenton varda 也可能是一个选择。我认为您最好自己尝试一下。

        提醒一下,RPC 不仅仅是远程对象调用。诸如足够的抽象和组合水平、流水线、消息传递、lambda 演算、能力安全等关注领域是必须密切关注的重要领域。因此,更好的解决方案是为您的问题空间找到高效且优雅的解决方案。

        希望能提供帮助。

        最好的, 奥米德

        【讨论】:

          猜你喜欢
          • 2014-08-08
          • 2015-07-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多