I'm trying to set up "inverted" PUB/SUB with ZeroMQ.
Meaning that subscribing (SUB) sockets belong to several long-living servers, doing zmq_bind()
; and publishing (PUB) socket is a short-lived client and does zmq_connect()
.
I use a single ipc://
socket.
I expect that a message from the publisher will reach each of subscribers.
The problem: Only one of subscriber processes ever receives messages. If that process dies, publisher gets stuck in zmq_term()
.
Is this mode of operations supported by zmq? If yes, then what am I doing wrong? If no, then how to implement what I need?
Minimal example with some additional details (in Lua, but this should not matter): https://gist.github.com/938429
ZeroMQ supports common messaging patterns (pub/sub, request/reply, client/server and others) over a variety of transports (TCP, in-process, inter-process, multicast, WebSocket and more), making inter-process messaging as simple as inter-thread messaging. This keeps your code clear, modular and extremely easy to scale.
Pub/Sub is a pattern where the publisher is not programmed to send a message (payload) to a specific receiver. These messages are sent by publishers to specific channels, and receivers can subscribe to one or more channels to consume those same messages.
To track subscriptions, Redis uses a global variable pubsub_channels which maps channel names to sets of subscribed client objects. A client object represents a TCP-connected client by tracking that connection's file descriptor.
Publish/subscribe messaging, or pub/sub messaging, is a form of asynchronous service-to-service communication used in serverless and microservices architectures. In a pub/sub model, any message published to a topic is immediately received by all of the subscribers to the topic.
You can't bind multiple sockets to one ipc://
address (we are talking about Unix Domain Socket here ipc:///tmp/test.ipc == file /tmp/test.ipc).
What you can do is bind each SUB socket to a different ipc:// address and have the publisher connect one PUB socket to each of those addresses. ZeroMQ allows one socket to bind/connect to multiple addresses.
The blocking on zmq_term() is most likely do to lingering close issue (i.e. there is a message that the PUB socket is trying to send). Take a look at the ZMQ_LINGER socket option.
There's a 'feature' of the ipc:// transport which is that if two processes bind to the same IPC endpoint, the second one will silently steal the binding from the first one. This 'feature' was made to allow processes to recover easily after a crash.
This is why only one subscriber is getting the messages.
Since you have just one publisher, why not bind the publisher, and connect the subscribers to that? Even if the publisher comes and goes, the subscribers will reconnect automatically.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With