Search code examples
c#zeromqnetmq

How to send ACK message to client from server using NetMQ


I am using NetMQ to send messages from many clients to a server which receives the messages and processes them. If I use the pub/sub pattern, I can (ab)use the subscriber socket and use it for the server and clients will be the publishers (the opposite flow, isn't it?). However, I cannot send an acknowledge message to the clients.

If I use the REQ/RESP pattern, I can use the response socket for the server and even send an acknowledge message which can be received by the client. However, if the server misses the message from client, I cannot resend the message (after waiting for a timespan), because I receive an exception

Req.XSend - cannot send another request

-- even after disconnecting the client socket and closing it (it seams that the server socket keeps track of it).

And finally, based on the documentation, I'm not sure if the Dealer/Router is the right pattern to use. As I'm pretty sure that I'm stuck in a very common situation, is there any pattern to implement this scenario using NetMQ?


Solution

  • You are stuck in a very common problem, typically called "Reliable Request-Reply" in 0MQ parlance.

    There are several approaches described in the guide, the first is the "lazy pirate". In it you use a REQ/RESP socket pair as described (though REQ/ROUTER would work just as well, and probably better for more than one client). The solution is to dispose of the socket if your ACK times out and create a new one.

    The guide does note that swapping a DEALER for the REQ would solve the problem, but adds having to keep track of the envelope yourself. Unless you need async send/receive on the client side for some other reason, I would follow their advice and stick with REQ/ROUTER.

    A sample implementation of this pattern can be found on GitHub: https://github.com/NetMQ/Samples/tree/master/src/Pirate%20Pattern