web-dev-qa-db-ja.com

プロセス間呼び出しのための適切でシンプルなRPCライブラリはありますか?

組み込みのC++型の引数を使用して、クライアントプロセスからサーバープロセスに(おそらく1つの)単純な一方向コマンドを送信する必要があります(したがって、シリアル化は非常に単純です)。 C++、Windows XP +。

私は、複雑な設定を必要とせず、シンプルなインターフェースを提供し、数時間から数日間の学習を必要とせず、商用利用制限のないライブラリを探しています。単純な問題に対する単純なソリューション。

Boost.Interprocess は、RPCインターフェイスを提供しないため、この単純なタスクには低レベルです。マシン間で通信する必要がないので、おそらくソケットも過剰です。 DCOM、CORBAなどについても同じです。名前付きパイプ?それらを使用したことはありません、WinAPI上の優れたライブラリですか? OpenMPI?

52
Andriy Tylychko

ソケットが本当に過剰だとは思わない。代替にはすべて独自の問題があり、ソケットはほとんどすべての人が使用しているため、名前付きパイプ、共有メモリなどよりもはるかに優れてサポートされています。ローカルシステムのソケットの速度はおそらく問題ではありません。

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/

メッセージがreallyシンプルな場合、UDPパケットの使用を検討するかもしれませんが、管理する接続はありません。

17
Tim Sylvester

このような場合は 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");
9
Imbrondir

Windowsのみをサポートする必要がある場合は、Windows組み込みのRPCを使用します。これについては、2つの紹介記事を書きました。

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

ローカルのプロセス間通信のみが必要な場合は、 ncalrpc プロトコルを使用できます。

6
dalle

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

Windowsのみで作業しており、実際にC++インターフェイスが必要な場合は、COM/DCOMを使用します。 RPCに基づいています(DCE RPCに基づいています)。

使い方は非常に簡単です-基本を学ぶのに時間がかかるなら。

3
Ben

私たちは使いやすいとはほど遠いことを知っています。しかしもちろん、CORBAに固執することもできます。例えば。 ACE/TAO

2
mkaes

おそらくライブラリさえ必要ないでしょう。 Windowsには、コアAPI(windows.h)に深く組み込まれたIPCメカニズムがあります。基本的に、異なるプロセスのメインウィンドウのメッセージキューにウィンドウメッセージを投稿できます。それを行うためのメッセージ:WM_COPYDATA。


送信プロセスは基本的に以下を行います。

受信プロセス(ウィンドウ):

2
edgar.holleis

RPCに Raknet は素晴らしくシンプルだと言われています。

1
Goz

また、あなたは 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

1
caentist

XmlRpc C++ for Windowsを使用しています ここにあります

本当に使いやすい:)しかし、これが唯一の副作用であるクライアントのみ!

0
RvdK

Microsoft Messaging Queueing もあります。これは、すべてのプロセスがローカルマシン上にある場合に使用するのはかなり簡単です。

0
Chris O