任何良好和简单的RPC库进程间调用?

我需要发送一个(可能是一个)简单的单向命令从客户端进程到服务器进程,内置C ++types的参数(所以序列化非常简单)。 C ++,Windows XP +。

我正在寻找一个不需要复杂的configuration,提供简单的界面,不需要几个小时的学习,并没有商业使用的限制。 简单的问题的解决scheme。

Boost.Interprocess对于这个简单的任务太低级,因为不提供RPC接口。 套接字也可能是一个矫枉过正,因为我不需要在机器之间进行通信。 关于DCOM,CORBA等也是如此。 命名pipe道? 从来没有使用过,WinAPI上的任何好的库? 的openmpi?

我不认为套接字真的是矫枉过正。 替代方法都有自己的问题,并且套接字比命名pipe道,共享内存等得到更好的支持,因为几乎每个人都在使用它们。 本地系统的套接字速度可能不是问题。

还有Apache Thrift:

http://incubator.apache.org/thrift/

作为编组机制,围绕Google的protobuf库有一些RPC实现:

https://github.com/google/protobuf/blob/master/docs/third_party.md#rpc-implementations

有XML-RPC:

http://xmlrpc-c.sourceforge.net/

如果你的消息非常简单,我可能会考虑使用UDP数据包,那么就没有连接要pipe理。

你可能喜欢ZeroMQ这样的东西。 也许不是一个完整的RPC,而是一个可以用来制作RPC的原始字节消息框架。 它简单,轻便,性能令人印象深刻。 你可以容易地在它上面实现一个RPC。 下面是一个直接来自手册的示例服务器:

// // Hello World server in C++ // Binds REP socket to tcp://*:5555 // Expects "Hello" from client, replies with "World" // #include <zmq.hpp> #include <unistd.h> #include <stdio.h> #include <string.h> int main () { // Prepare our context and socket zmq::context_t context (1); zmq::socket_t socket (context, ZMQ_REP); socket.bind ("tcp://*:5555"); while (true) { zmq::message_t request; // Wait for next request from client socket.recv (&request); printf ("Received Hello"); // Do some 'work' sleep (1); // Send reply back to client zmq::message_t reply (5); memcpy ((void *) reply.data (), "World", 5); socket.send (reply); } return 0; } 

本示例使用tcp://*.5555,但如果使用以下方法,则使用更高效的IPC技术:

 socket.bind("ipc://route.to.ipc"); 

甚至更快的线程间协议:

 socket.bind("inproc://path.for.client.to.connect"); 

如果你只需要支持Windows,我会使用Windows内置的RPC,我已经写了两篇介绍性的文章:

http://www.codeproject.com/KB/IP/r​​pcintro1.aspx
http://www.codeproject.com/KB/IP/r​​pcintro2.aspx

如果您只需要本地进程间通信,则可以使用ncalrpc协议。

Boost.MPI 。 简单,快速,可扩展。

 #include <boost/mpi/environment.hpp> #include <boost/mpi/communicator.hpp> #include <iostream> #include <sstream> namespace mpi = boost::mpi; int main(int argc, char* argv[]) { mpi::environment env(argc, argv); mpi::communicator world; std::stringstream ss; ss << "Hello, I am process " << world.rank() << " of " << world.size() << "."; world.send(1, 0, ss.str()); } 

你可能甚至不需要一个图书馆。 Windows有一个深入到其核心API(windows.h)中的IPC机制。 你基本上可以将一个Windows消息发布到不同进程主窗口的消息队列中。 Windows甚至定义了一个标准的消息:WM_COPYDATA。

  • WM_COPYDATA MSDN文件
  • MSDN 演示代码
  • 更多演示代码如下StackOverflow 响应

发送过程基本上是这样的:

  • FindWindow函数
  • 发信息

接收过程(窗口):

  • 在Vista和更高版本必须使用ChangeWindowsMessageEx修改其消息filter
  • 覆盖它的WindowProc
  • 为了处理传入的WM_COPYDATA

我知道我们远离易于使用。 但是当然你可以坚持到CORBA。 如ACE / TAO

如果您只在Windows上工作,并且确实需要C ++接口,请使用COM / DCOM。 它基于RPC(反过来基于DCE RPC)。

这是非常简单的使用 – 如果你花时间学习的基础知识。

  • ATL: http : //msdn.microsoft.com/en-us/library/3ax346b7( VS.71) .aspx
  • 接口定义语言: http : //msdn.microsoft.com/en-us/library/aa367091(VS.85).aspx

我被告知RPC与Raknet是很好,很简单。

另外,你可以看看msgpack-rpc

更新

虽然Thrift / Protobuf更灵活,但我认为,但是需要以特定格式编写一些代码。 例如,Protobuf需要一些.proto文件,这个文件可以通过包中的特定编译器进行编译,生成一些类。 在某些情况下,代码的其他部分可能会更困难。 msgpack-rpc要简单得多。 它不需要写一些额外的代码。 这里是例子:

 #include <iostream> #include <msgpack/rpc/server.h> #include <msgpack/rpc/client.h> class Server: public msgpack::rpc::dispatcher { public: typedef msgpack::rpc::request request_; Server() {}; virtual ~Server() {}; void dispatch(request_ req) try { std::string method; req.method().convert(&method); if (method == "id") { id(req); } else if (method == "name") { name(req); } else if (method == "err") { msgpack::type::tuple<> params; req.params().convert(&params); err(req); } else { req.error(msgpack::rpc::NO_METHOD_ERROR); } } catch (msgpack::type_error& e) { req.error(msgpack::rpc::ARGUMENT_ERROR); return; } catch (std::exception& e) { req.error(std::string(e.what())); return; } void id(request_ req) { req.result(1); } void name(request_ req) { req.result(std::string("name")); } void err(request_ req) { req.error(std::string("always fail")); } }; int main() { // { run RPC server msgpack::rpc::server server; std::auto_ptr<msgpack::rpc::dispatcher> dispatcher(new Server); server.serve(dispatcher.get()); server.listen("0.0.0.0", 18811); server.start(1); // } msgpack::rpc::client c("127.0.0.1", 18811); int64_t id = c.call("id").get<int64_t>(); std::string name = c.call("name").get<std::string>(); std::cout << "ID: " << id << std::endl; std::cout << "name: " << name << std::endl; return 0; } 

产量

 ID: 1 name: name 

更复杂的例子,你可以在这里findhttps://github.com/msgpack/msgpack-rpc/tree/master/cpp/test

我使用XmlRpc C ++ for Windows 在这里find

真的好用:)但是这只是一个客户端的唯一副作用

还有Microsoft消息队列 ,当所有进程都在本地计算机上时,这是非常简单的。

进程间通信最简单的解决scheme是使用文件系统。 请求和响应可以写成临时文件。 您可以为请求和响应文件制定一个命名约定。

这不会给你最好的performance,但也许它会足够好。