любая хорошая и простая библиотека RPC для межпроцессных вызовов? [закрытый]

Мне нужно отправить (возможно, одну) простую одностороннюю команду из клиентских процессов в серверный процесс с аргументами встроенных типов C++ (поэтому сериализация довольно проста). C++, Windows XP+.

Я ищу библиотеку, которая не требует сложной конфигурации, обеспечивает простой интерфейс, не требует часов до дней обучения и не имеет ограничений коммерческого использования. Простое решение для простой задачи.

импульс.Interprocess is слишком низкий уровень для этой простой задачи, потому что не предоставляет интерфейс RPC. Сокеты, вероятно, тоже излишни, потому что мне не нужно общаться между машинами. То же самое касается DCOM, CORBA и др. По имени Пайпс? Никогда не использовал их, любую хорошую библиотеку над WinAPI? Openmpi с?

12 ответов


Я не думаю, что розетки действительно перебор. У всех альтернатив есть свои проблемы, и сокеты гораздо лучше поддерживаются, чем именованные каналы, общая память и т. д. потому что почти все ими пользуются. Скорость сокетов в локальной системе, вероятно, не является проблемой.

есть Apache бережливость:

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

есть несколько реализаций RPC, обернутых вокруг библиотеки protobuf Google в качестве маршалинга механизм:

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

есть XML-RPC:

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

Если ваши сообщения действительно простой, я мог бы рассмотреть использование 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, я бы использовал встроенный RPC Windows, я написал две вводные статьи об этом:

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

можно использовать ncalrpc протокол, если вам нужна только локальная межпроцессная связь.


импульс.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 (в свою очередь, на RPC DCE).

Это чрезвычайно прост в использовании, при условии, что вы берете время, чтобы изучить основы.


вам не нужна библиотека. Windows имеет механизм IPC, встроенный глубоко в его основные API (windows.ч.) Вы можете в основном разместить сообщение windows в очереди сообщений главного окна разных процессов. Windows даже определяет стандартное сообщение для этого: WM_COPYDATA.


процесс отправки в основном делает:

процесс получения (окно):


Я знаю, что мы далеки от простого в использовании. Но, конечно, вы можете придерживаться КОРБЫ. Е. Г. ТУЗ/ТАУ


Мне сказали RPC с Raknet приятно и просто.


кроме того, вы можете посмотреть на msgpack-rpc

обновление

в то время как бережливость/Протобуф более гибкие, я думаю, но требуется написать некоторый код в определенном формате. Например, Protobuf нужна .прото файл, который можно скомпилировать с конкретными компилятор из пакета, что genegate некоторых классов. В некоторых случаях это может быть сложнее, чем другие части кода. 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


Я использую XmlRpc C++ для Windows найти здесь

очень проста в использовании :) но единственный побочный эффект, что это только клиент!


там же Обмена Сообщениями Microsoft Массового Обслуживания, который довольно прост в использовании, когда все процессы находятся на локальном компьютере.


самым простым решением для межпроцессной связи является использование файловой системы. Запросы и ответы могут быть записаны как временные файлы. Вы можете разработать соглашение об именах для файлов запросов и ответов.

Это не даст вам лучшую производительность, но, возможно, это будет достаточно хорошо.