組み込みのC++型の引数を使用して、クライアントプロセスからサーバープロセスに(おそらく1つの)単純な一方向コマンドを送信する必要があります(したがって、シリアル化は非常に単純です)。 C++、Windows XP +。
私は、複雑な設定を必要とせず、シンプルなインターフェースを提供し、数時間から数日間の学習を必要とせず、商用利用制限のないライブラリを探しています。単純な問題に対する単純なソリューション。
Boost.Interprocess は、RPCインターフェイスを提供しないため、この単純なタスクには低レベルです。マシン間で通信する必要がないので、おそらくソケットも過剰です。 DCOM、CORBAなどについても同じです。名前付きパイプ?それらを使用したことはありません、WinAPI上の優れたライブラリですか? OpenMPI?
ソケットが本当に過剰だとは思わない。代替にはすべて独自の問題があり、ソケットはほとんどすべての人が使用しているため、名前付きパイプ、共有メモリなどよりもはるかに優れてサポートされています。ローカルシステムのソケットの速度はおそらく問題ではありません。
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パケットの使用を検討するかもしれませんが、管理する接続はありません。
このような場合は 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を使用します。これについては、2つの紹介記事を書きました。
http://www.codeproject.com/KB/IP/rpcintro1.aspx
http://www.codeproject.com/KB/IP/rpcintro2.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のみで作業しており、実際にC++インターフェイスが必要な場合は、COM/DCOMを使用します。 RPCに基づいています(DCE RPCに基づいています)。
使い方は非常に簡単です-基本を学ぶのに時間がかかるなら。
私たちは使いやすいとはほど遠いことを知っています。しかしもちろん、CORBAに固執することもできます。例えば。 ACE/TAO
おそらくライブラリさえ必要ないでしょう。 Windowsには、コアAPI(windows.h)に深く組み込まれたIPCメカニズムがあります。基本的に、異なるプロセスのメインウィンドウのメッセージキューにウィンドウメッセージを投稿できます。それを行うためのメッセージ:WM_COPYDATA。
送信プロセスは基本的に以下を行います。
受信プロセス(ウィンドウ):
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(¶ms);
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
XmlRpc C++ for Windowsを使用しています ここにあります
本当に使いやすい:)しかし、これが唯一の副作用であるクライアントのみ!
Microsoft Messaging Queueing もあります。これは、すべてのプロセスがローカルマシン上にある場合に使用するのはかなり簡単です。