Depends on your language choice. If, for example, you use node.js, everything is callbacks.
You don't specify your language choice, or what's going on in your application. Typically your strategy will depend on the overall nature of your application.
The reason you'll typically see a loop that is solely focused on receiving messages is twofold:
- These are examples, and that's the easiest way to write an example that will receive and deal with a message efficiently.
- ZMQ is a high volume toolset, typically when you're using it receiving messages is a high priority task for you, so dedicating an entire thread to receiving those messages might be a good idea.
That said, if you can define some larger loop in your application that you can receive messages once or only periodically during, you can just delegate the task to that larger loop. Say, something like (psuedocode):
while (functional_task) {
while (msg = socket.recv()) {
handle(msg);
}
do_other_stuff();
}
... that way you're processing all queued messages once per functional loop, rather than having a loop solely dedicated to your messages.
Whether or not you can use a callback system is largely dependent upon your language and ZMQ binding.