Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 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");

Ответ 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.


Процесс отправки в основном выполняет:

Процесс приема (окно):

  • В Vista и позже необходимо изменить свой фильтр сообщений, используя ChangeWindowsMessageEx
  • Отменить его WindowProc
  • Для обработки входящего 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(&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

Ответ 10

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

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

Ответ 11

Там также Microsoft Messaging Queuing, что довольно просто использовать, когда все процессы находятся на локальной машине.

Ответ 12

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

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