I know, I know, comparing ZeroMQ and DBus is like comparing apples and oranges… But, in my small tiny use case, it does make sense !
The use case is simple, I want to implement an Publish-Subscribe IPC architecture. And both ZeroMQ and DBus permit this kind of architecture.
What is DBus ?
“D-Bus is a message bus system, a simple way for applications to talk to one another. In addition to interprocess communication, D-Bus helps coordinate process lifecycle; it makes it simple and reliable to code a "single instance" application or daemon, and to launch applications and daemons on demand when their services are needed.” (https://www.freedesktop.org/wiki/Software/dbus/)
Sounds like it should work right ? Plus, before restructuring the project, I used a bit the QtDBus module, which is easy enough to grasp and use.
But, without Qt, in C++, how do you implement a DBus interface ? Or, what library should one use to use DBus in C++ ?
Well that’s where it falls apart from my point of view.
You either get very old and/or under-documented projects, or libraries that are meant to be used in a specific context (Qt, GLib, openBMC, etc.).
You could go with the official C lib but it is a low level implementation, and they even discourage you from it !
“If you use this low-level API directly, you're signing up for some pain.” (https://dbus.freedesktop.org/doc/api/html/index.html)
I tried my hands with a few of them but nothing was really satisfying.
And the whole ‘interface’ and ‘adaptors’ DBus concepts in C++ means adding somewhere some kind of proxy class for every class you need to expose to the outside and I never felt comfortable with using those.
And them came ZeroMQ !
I remembered watching the video a while back : https://www.youtube.com/watch?v=v6AGUeZOVSU
I would advise watching this video if you want to know what ZeroMQ is. But to quote them :
“ZeroMQ (also known as ØMQ, 0MQ, or zmq) looks like an embeddable networking library but acts like a concurrency framework. It gives you sockets that carry atomic messages across various transports like in-process, inter-process, TCP, and multicast. You can connect sockets N-to-N with patterns like fan-out, pub-sub, task distribution, and request-reply. It's fast enough to be the fabric for clustered products. Its asynchronous I/O model gives you scalable multicore applications, built as asynchronous message-processing tasks. It has a score of language APIs and runs on most operating systems. ZeroMQ is from iMatix and is LGPLv3 open source.” (http://zguide.zeromq.org/page:all#ZeroMQ-in-a-Hundred-Words)
I started using it and in literally 4 lines of code…
zmqpp::context context; // [...] zmqpp::socket zmqPubSocket(*context, zmqpp::socket_type::publish); zmqPubSocket.bind("tcp://127.0.0.1:6661"); // [...] zmqPubSocket.send("... spectrum data ...");
Booom ! I was publishing messages on a tcp port.
The cool thing is : just by setting the endpoint of your communications you can send messages through the network (“tcp://0.0.0.0:8080” for example) or locally through the device filesystem (“ipc:///tmp/messages/topic” for example).
This means a lot for this project, because, by making these endpoints configurable at runtime, you will be able to stream spectrum levels across the internet with no effort.
There is much more to ZMQ than just Publish-Subscribe, I will also use to build a controller interface with a Request-Response pattern, add a security layer, etc…
Anyway I believe it is both a solid and flexible foundation for what is to come.
Imagine a “smart” city using it to gather noise levels from their many sound monitoring raspberry pi everywhere …