Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I do multiple publishers with a single endpoint in ZeroMQ?

I'm attempting to do a pub/sub architecture where multiple publishers and multiple subscribers exist on the same bus. According to what I've read on the internet, only one socket should ever call bind(), and all others (whether pub or sub) should call connect().

The problem is, with this approach I'm finding that only the publisher that actually calls bind() on the socket ever publishes messages. All of my publishers that call connect() seem to fail silently and don't actually publish any messages to the bus. I've confirmed this isn't a subscriber key issue, as I've written a simple "sniffer" app that subscribes to all messages on the bus, and it is only showing the publisher that called bind().

If I attempt multiple binds with the publisher, the "expected" zmq behavior of silently stealing the bus occurs with ipc, and a port in use error is thrown with tcp.

I've verified this behavior with ipc and tcp endpoints, but ultimately the full system will be using epgm. I assume (though of course may be wrong) that in this situation I wouldn't need a broker since there's no dynamic discovery occurring (endpoints are known, whether ipc, tcp, or epgm multicast).

Is there something I'm missing, perhaps a socket setting, that would be causing the connecting publishers to not actually send their data? According to the literature I've seen on the internet, I'm doing things the "correct" way but it still doesn't work.

For reference, my publisher class has the following methods for setting up the endpoint:

ZmqPublisher::ZmqPublisher()
: m_zmqContext(1), m_zmqSocket(m_zmqContext, ZMQ_PUB)
{}


void ZmqPublisher::bindEndpoint(std::string ep)
{
    m_zmqSocket.bind(ep.c_str());
}

void ZmqPublisher::connect(std::string ep)
{
    m_zmqSocket.connect(ep.c_str());
}

So ultimately, my question is this: What is the proper way to handle multiple publishers on the same endpoint, and why am I not seeing messages from more than one publisher?

like image 552
stix Avatar asked Aug 26 '13 16:08

stix


People also ask

What is zmq socket?

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.

Does pub/sub use TCP?

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.

What is topic in zmq?

Topics. ZeroMQ uses multipart messages to convey topic information. Topics are expressed as an array of bytes, though you may use a string and with suitable text encoding. A publisher must include the topic in the message's' first frame, prior to the message payload.


2 Answers

It may or may not be relevant, but The 0MQ Guide has the following slightly enigmatic remark:

In theory with ØMQ sockets, it does not matter which end connects and which end binds. However, in practice there are undocumented differences that I'll come to later. For now, bind the PUB and connect the SUB, unless your network design makes that impossible.

I've not yet discovered where the "come to later" actually happens, but I don't use pub/sub so much, and haven't read the "Advanced Pub-Sub Patterns" part of the guide in great detail.

However, the idea of multiple publishers on a single end-point, to me, suggests the need for an XPUB/XSUB style broker; it's not about dynamic discovery, it's about single point of contact and routing. Ultimately, I think a broker-based topology would simplify your application, and make it easier to identify problems.

like image 118
SteveLove Avatar answered Oct 15 '22 13:10

SteveLove


Your mistake was that you call a single publisher with bind and others with connect. This is not supported with plain PUB-SUB pattern.

Plain PUB-SUB in ZeroMQ supports only two scenarios (see the image below):

  • single publisher, multiple subscribers
  • single subscriber, multiple publishers

In both cases, the party that is "single" must bind and the party that is "multiple" must connect. Otherwise, if you want many-to-many, you can use XPUB-XSUB or some other pattern.

ZeroMQ / ZMQ / ØMQ Pub-Sub pattern. Two scenarios: 1) single publisher, multiple subscribers; 2) single subscriber, multiple publishers
like image 34
Andriy Makukha Avatar answered Oct 15 '22 13:10

Andriy Makukha