1

I have a program where there's a ZMQ_SUB socket at the client side, and a ZMQ_PUB socket at the server side, and the client subscribes to the server:

Pretty straightforward code:

client side:

zmq::socket_t subscriber(context, ZMQ_SUB);     
subscriber.connect("tcp://xxx:xxx");    
subscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0);

server side:

zmq::socket_t publisher(zmqContext, ZMQ_PUB);
publisher->bind("tcp://*.xxx");

I use another pair of ZMQ_REQ, ZMQ_REP sockets between the client and server. Everytime the client sends some request to the server via the ZMQ_REQ socket, the server receives it via the ZMQ_REP socket, does some work, responds via the REP socket, and in the meantime, generate a bunch of messages, and publish them via the ZMQ_PUB socket.

Most of the time, the client is able to receive messages from the ZMQ_SUB socket, but I do have cases where the client doesn't receive those messages.

The messages are guaranteed to be generated at the server side, and they're published immediately upon generation.

Is it normal? Or is there something wrong with my usage/settings, that leads to this undeterministic behavior. (Client side SUB socket not receiving messages sometimes)

mpromonet
  • 11,326
  • 43
  • 62
  • 91
Yang Ye
  • 11
  • 3
  • You may want to read **whathaveyoutried.com** & show some respect to the StackOverflow Community, which strongly encourages to post high quality questions, altogether with a MCVE ( **a Minimum-Complete-Verifiable-Example of code ) showing what-you-have-tried so far.** You may want to update your post, so as to meet this minimum reasonable level of quality & to show your will to respect other StackOverflow contributing members. They are professionals who love to answer good questions on MCVE-related issues. **Enjoy being StackOverflow Contributing Member & do support this Community Netiquette** – user3666197 Jan 31 '15 at 18:37

1 Answers1

2

Is it normal?

such question is so easy to be asked, but so hard to get answered with no other details and contexts available.

ZeroMQ "Missing Message Problem" chapter in the great Pieter HINTJENS' book "Code Connected Volume 1" says a few general principles on this subject:


• On SUB sockets, set a subscription using zmq_setsockopt() with ZMQ_SUBSCRIBE, or you won’t get messages. Because you subscribe to messages by prefix, if you subscribe to "" (an empty subscription), you will get everything.

• If you start the SUB socket (i.e., establish a connection to a PUB socket) after the PUB socket has started sending out data, you will lose whatever it published before the connection was made. If this is a problem, set up your architecture so the SUB socket starts first, then the PUB socket starts publishing.

• Even if you synchronize a SUB and PUB socket, you may still lose messages. It’s due to the fact that internal queues aren’t created until a connection is actually created. If you can switch the bind/connect direction so the SUB socket bind-s, and the PUB socket connect-s, you may find it works more as you’d expect.

• If you’re using REP and REQ sockets, and you’re not sticking to the synchronous send/recv/send/recv order, ØMQ will report errors, which you might ignore. Then, it would look like you’re losing messages. If you use REQ or REP, stick to the send/recv order, and always, in real code, check for errors on ØMQ calls.

• If you’re using PUSH sockets, you’ll find that the first PULL socket to connect will grab an unfair share of messages. The accurate rotation of messages only happens when all PULL sockets are successfully connected, which can take some milliseconds. As an alternative to PUSH/PULL, for lower data rates, consider using ROUTER/DEALER and the load balancing pattern.

• If you’re sharing sockets across threads, don’t. It will lead to random weirdness, and crashes.

• If you’re using inproc, make sure both sockets are in the same context. Otherwise the connecting side will in fact fail. Also, bind first, then connect. inproc is not a disconnected transport like tcp.

• If you’re using ROUTER sockets, it’s remarkably easy to lose messages by accident, by sending malformed identity frames (or forgetting to send an identity frame). In general setting the ZMQ_ROUTER_MANDATORY option on ROUTER sockets is a good idea, but do also check the return code on every send call.

• Lastly, if you really can’t figure out what’s going wrong, make a minimal test case that reproduces the problem, and ask for help from the ØMQ community.

user3666197
  • 1
  • 6
  • 50
  • 92