Любая хорошая и простая библиотека RPC для межпроцессных вызовов?
Мне нужно отправить (возможно одну) простую одностороннюю команду от клиентских процессов к серверному процессу с аргументами встроенных типов С++ (поэтому сериализация довольно проста). С++, Windows XP +.
Я ищу библиотеку, которая не требует сложной конфигурации, обеспечивает простой интерфейс, не требует от нескольких часов до нескольких дней обучения и не имеет коммерческих ограничений использования. Простое решение для простой задачи.
Boost.Interprocess слишком низкоуровневый для этой простой задачи, потому что не обеспечивает интерфейс RPC. Розетки, вероятно, слишком переполнены, потому что мне не нужно общаться между машинами. То же самое касается DCOM, CORBA и др. Именованные трубы? Никогда не использовали их, какую-либо хорошую библиотеку поверх WinAPI? OpenMPI?
Ответы
Ответ 1
Я не думаю, что сокеты действительно переборщит. Все альтернативы имеют свои проблемы, и сокеты намного лучше поддерживаются, чем именованные каналы, разделяемая память и т.д., Потому что почти все используют их. Скорость сокетов в локальной системе, вероятно, не проблема.
Там Apache Thrift:
http://incubator.apache.org/thrift/
Существует несколько реализаций RPC, обернутых вокруг Google protobuf library в качестве механизма маршалинга:
https://github.com/google/protobuf/blob/master/docs/third_party.md#rpc-implementations
Там XML-RPC:
http://xmlrpc-c.sourceforge.net/
Если ваши сообщения действительно просты, я могу рассмотреть возможность использования UDP-пакетов, тогда нет связей для управления.
Ответ 2
Вам может понравиться 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");
или даже более быстрый протокол inter thread:
socket.bind("inproc://path.for.client.to.connect");
Ответ 3
Если вам нужна только поддержка Windows, я бы использовал встроенный RPC для Windows, я написал две вступительные статьи об этом:
http://www.codeproject.com/KB/IP/rpcintro1.aspx
http://www.codeproject.com/KB/IP/rpcintro2.aspx
Вы можете использовать протокол ncalrpc
, если вам нужна только локальная межпроцессная связь.
Ответ 4
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
Вам, вероятно, даже не нужна библиотека. Windows имеет механизм IPC, встроенный в его основные API (windows.h). Вы можете отправить сообщение Windows в очередь сообщений в главном окне разных процессов. Windows даже определяет стандартное сообщение, чтобы сделать именно это: WM_COPYDATA.
Процесс отправки в основном выполняет:
Процесс приема (окно):
Ответ 6
Я знаю, что мы далеко от простого в использовании. Но, конечно, вы можете придерживаться CORBA. Например. ACE/TAO
Ответ 7
Если вы работаете только с окнами и действительно нуждаетесь в С++-интерфейсе, используйте COM/DCOM. Он основан на RPC (в свою очередь, на основе DCE RPC).
Это чрезвычайно простое использование - при условии, что вы нашли время, чтобы изучить основы.
Ответ 8
Мне говорят, что RPC с Raknet приятный и простой.
Ответ 9
Кроме того, вы можете посмотреть msgpack-rpc
Update
Хотя 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
Ответ 10
Я использую XmlRpc С++ для Windows найденный здесь
Действительно прост в использовании:) Но единственный побочный эффект, что это только клиент!
Ответ 11
Там также Microsoft Messaging Queuing, что довольно просто использовать, когда все процессы находятся на локальной машине.
Ответ 12
Простейшим решением для межпроцессного взаимодействия является использование файловой системы. Запросы и ответы могут быть записаны как временные файлы. Вы можете разработать соглашение об именах для файлов запросов и ответов.
Это не даст вам лучшую производительность, но, возможно, это будет достаточно хорошо.