c++ rpc interprocess

c++ - ¿Alguna buena y simple biblioteca RPC para llamadas entre procesos?



interprocess (12)

Necesito enviar un (probablemente uno) comando simple de un solo sentido desde los procesos del cliente al proceso del servidor con argumentos de tipos C ++ incorporados (por lo que la serialización es bastante simple). C ++, Windows XP +.

Estoy buscando una biblioteca que no requiera una configuración complicada, que ofrezca una interfaz simple, no requiera horas o días de aprendizaje y no tenga restricciones de uso comercial. Solución simple para un problema simple.

Boost.Interprocess tiene un nivel demasiado bajo para esta tarea simple porque no proporciona una interfaz RPC. Los sockets también son una exageración porque no necesito comunicarme entre máquinas. Lo mismo sobre DCOM, CORBA et al. ¿Tuberías con nombre? Nunca los usé, ¿alguna buena biblioteca sobre WinAPI? OpenMPI?


Además, puede ver msgpack-rpc

Actualizar

Aunque Thrift / Protobuf son más flexibles, creo, pero se requieren para escribir algún código en formato específico. Por ejemplo, Protobuf necesita algún archivo .proto, que puede compilarse con un compilador específico del paquete, que genere algunas clases. En algunos casos, podría ser más difícil que otras partes del código. msgpack-rpc es mucho más simple. No requiere escribir un código adicional. Aquí hay un ejemplo:

#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; }

Salida

ID: 1 name: name

Ejemplos más complicados que puedes encontrar aquí https://github.com/msgpack/msgpack-rpc/tree/master/cpp/test


Estoy usando XmlRpc C ++ para Windows encontrado aquí

Realmente fácil de usar :) ¡Pero el único efecto secundario es que este es solo un cliente!


La solución más simple para la comunicación entre procesos es usar el sistema de archivos. Las solicitudes y las respuestas se pueden escribir como archivos temporales. Puede elaborar una convención de nomenclatura para los archivos de solicitud y respuesta.

Esto no le dará el mejor rendimiento, pero tal vez será lo suficientemente bueno.


Me dijeron que RPC con Raknet es agradable y simple.


No creo que los enchufes sean excesivos. Todas las alternativas tienen sus propios problemas y los sockets son mucho más compatibles que los named pipes, la memoria compartida, etc., porque casi todos los usan. La velocidad de los enchufes en el sistema local probablemente no sea un problema.

Hay Apache Thrift:

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

Hay algunas implementaciones de RPC envueltas en la biblioteca de protobuf de Google como el mecanismo de clasificación:

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

Hay XML-RPC:

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

Si sus mensajes son realmente simples, podría considerar el uso de paquetes UDP, entonces no hay conexiones para administrar.


Probablemente ni siquiera necesites una biblioteca. Windows tiene un mecanismo de IPC integrado profundamente en sus API principales (windows.h). Básicamente puede publicar un mensaje de Windows en la cola de mensajes de una ventana principal de procesos diferentes. Windows incluso define un mensaje estándar para hacer justamente eso: WM_COPYDATA.

El proceso de envío básicamente lo hace:

El proceso de recepción (ventana):


Sé que estamos lejos de ser fáciles de usar. Pero, por supuesto, puedes apegarte a CORBA. Ej. ACE/TAO





Boost.MPI . Simple, rápido, escalable.

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


Es posible que le guste ZeroMQ para algo como esto. Tal vez no tanto un RPC completo, como un marco de mensajería de bytes sin procesar que podría usar para hacer un RPC. Es simple, ligero y con un rendimiento impresionante. Usted puede implementar fácilmente una RPC además de eso. Aquí hay un servidor de ejemplo directamente del manual:

// // 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; }

Este ejemplo usa tcp: //*.5555, pero usa técnicas de IPC más eficientes si usa:

socket.bind("ipc://route.to.ipc");

o incluso un protocolo entre hilos más rápido:

socket.bind("inproc://path.for.client.to.connect");