any good and simple RPC library for inter-process calls?

C++RpcInterprocess

C++ Problem Overview


I need to send a (probably one) simple one-way command from client processes to server process with arguments of builtin C++ types (so serialization is pretty simple). C++, Windows XP+.

I'm looking for a library that doesn't require complicated configuration, provides simple interface, doesn't require hours to days of learning and doesn't have commercial usage restrictions. Simple solution for simple problem.

Boost.Interprocess is too low-level for this simple task because doesn't provide RPC interface. Sockets are probably an overkill too because I don't need to communicate between machines. The same about DCOM, CORBA et al. Named pipes? Never used them, any good library over WinAPI? OpenMPI?

C++ Solutions


Solution 1 - C++

I don't think sockets are really overkill. The alternatives all have their own problems and sockets are far better supported than named pipes, shared memory, etc., because almost everyone is using them. The speed of sockets on local system is probably not an issue.

There's Apache Thrift:

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

There are a few RPC implementations wrapped around Google's protobuf library as the marshaling mechanism:

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

There's XML-RPC:

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

If your messages are really simple, I might consider using UDP packets, then there are no connections to manage.

Solution 2 - C++

You might like ZeroMQ for something like this. Perhaps not as much a complete RPC, as a raw byte messaging framework you could use to make an RPC. It's simple, lightweight and with an impressive performance. You can easilly implement an RPC on top of it. Here's an example server straight from the 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;
}

This example uses tcp://*.5555, but uses more efficient IPC techniques if you use:

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

or even faster inter thread protocol:

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

Solution 3 - C++

If you only need to support Windows I'd use the Windows built-in RPC, I've written two introductory articles about this:

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

You could use the ncalrpc protocol if you only need local inter-process communication.

Solution 4 - C++

Boost.MPI. Simple, fast, scalable.

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

Solution 5 - C++

If you are working on windows only, and really need a C++ interface, use COM/DCOM. It is based on RPC (in turn based on DCE RPC).

It is extremely simple to use -- provided you take the time to learn the basics.

Solution 6 - C++

You probably don't even need a library. Windows has an IPC mechanism built deeply into its core APIs (windows.h). You can basically post a windows message into the message-queue of a different processes main window. Windows even defines a standard message to do just that: WM_COPYDATA.


The sending process basically does:

The receiving process (window):

Solution 7 - C++

I know that we are far away from easy to use. But of course you can stick to CORBA. E.g. ACE/TAO

Solution 8 - C++

I'm told RPC with Raknet is nice and simple.

Solution 9 - C++

Also, you might look at msgpack-rpc

Update

While Thrift/Protobuf are more flexible, I think, but there are require to write some code in specific format. For example, Protobuf needs some .proto file, which can be compile with specific compiler from package, that genegate some classes. In some cases it might be more difficult that other parts of code. msgpack-rpc is much simpler. It doesn't require write some extra code. Here is example:

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

Output

ID: 1
name: name

More complicated examples you can find here https://github.com/msgpack/msgpack-rpc/tree/master/cpp/test

Solution 10 - C++

I'm using XmlRpc C++ for Windows found here

Really easy to use :) But the only side effect that this is only a client!

Solution 11 - C++

There's also Microsoft Messaging Queueing, which is fairly straightforward to use when all processes are on the local machine.

Solution 12 - C++

The simplest solution for interprocess-communication is to use the filesystem. Requests and responses can be written as temp files. You can work out a naming convention for request and response files.

This will not give you the best performance, but maybe it will be good enough.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndriy TylychkoView Question on Stackoverflow
Solution 1 - C++Tim SylvesterView Answer on Stackoverflow
Solution 2 - C++ImbrondirView Answer on Stackoverflow
Solution 3 - C++dalleView Answer on Stackoverflow
Solution 4 - C++log0View Answer on Stackoverflow
Solution 5 - C++BenView Answer on Stackoverflow
Solution 6 - C++edgar.holleisView Answer on Stackoverflow
Solution 7 - C++mkaesView Answer on Stackoverflow
Solution 8 - C++GozView Answer on Stackoverflow
Solution 9 - C++asukharevView Answer on Stackoverflow
Solution 10 - C++RvdKView Answer on Stackoverflow
Solution 11 - C++Chris OView Answer on Stackoverflow
Solution 12 - C++StackedCrookedView Answer on Stackoverflow