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

2

12

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?

Electromagnet answered 26/8, 2013 at 16:18 Comment(1)
Your question is not clear; consider revising.Selia
A
7

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
Acarus answered 29/5, 2021 at 14:19 Comment(0)
T
4

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.

Toweling answered 27/8, 2013 at 13:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.