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

时间:2011-03-22 22:33:07

标签: c++ rpc interprocess

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

我正在寻找一个不需要复杂配置的库,提供简单的界面,不需要数小时的学习时间,也没有商业使用限制。解决简单问题的简单方法。

Boost.Interprocess对于这个简单的任务来说太低级了,因为它不提供RPC接口。套接字也可能是一种过度杀伤,因为我不需要在机器之间进行通信。关于DCOM,CORBA等人也是如此。命名管道?从未使用过它们,WinAPI上的任何好库?的openmpi?

12 个答案:

答案 0 :(得分:17)

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

有Apache Thrift:

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

有一些RPC实现包含在Google的protobuf库中作为编组机制:

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

有XML-RPC:

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

如果您的消息真的简单,我可能会考虑使用UDP数据包,然后没有可以管理的连接。

答案 1 :(得分:9)

您可能希望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");

答案 2 :(得分:6)

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

http://www.codeproject.com/KB/IP/rpcintro1.aspx
http://www.codeproject.com/KB/IP/rpcintro2.aspx

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

答案 3 :(得分:5)

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());
}

答案 4 :(得分:3)

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

使用极其简单 - 只要您花时间学习基础知识。

答案 5 :(得分:2)

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


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

接收过程(窗口):

答案 6 :(得分:2)

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

答案 7 :(得分:1)

我告诉RPC Raknet很简单。

答案 8 :(得分:1)

另外,您可以查看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

您可以在此处找到更复杂的示例https://github.com/msgpack/msgpack-rpc/tree/master/cpp/test

答案 9 :(得分:0)

我正在使用XmlRpc C ++ for Windows found here

真的很容易使用:)但唯一的副作用是只是一个客户端!

答案 10 :(得分:0)

还有Microsoft Messaging Queueing,当所有进程都在本地计算机上时,使用起来非常简单。

答案 11 :(得分:-3)

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

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