I'm working on distributed application. The networking is based on ZMQ (jeromq), here's my architecture:
N Clients (Dealer socket) <---> (Router) Proxy (Dealer) <---> 1 (Dealer) Reciving Worker
<---> N (Dealer) Processing Workers
When a client sends a message, it is received by the receiving worker, placed in the queue, the processing worker picks it up does some processing and sends it back, the client receives the response after which it sends another request, that request is not being received by the receiving worker but it is sent by the client. Basically only the first 'round' works. What am i missing here ?!
What you're missing is that Dealer sockets send out messages to any connected client in a round robin fashion. The upshot is that your architecture won't work the way you intend.
To start, I'll write up a more accurate diagram of your intended architecture (for the moment, I'm ignoring socket types):
Client <-----> Broker ------> Receiver
^ |
| |
\ v
---------- Processor
When you send the first message, it gets sent to the receiver - because it's the first connected socket in the queue. When you send the second message, the DEALER
socket on your broker is sending to the next socket in the queue, in a round-robin fashion, which is the first processor. Basically, the problem is that your broker isn't able to distinguish between your "receiver" socket and your "processor" sockets, it treats them all as the same thing.
There are a couple ways you could handle this. First of all, you probably don't really need your "receiver" socket as a go-between, you may be able to communicate directly back and forth between your broker and your processing workers. I'd suggest that first, as that's typically how these types of architectures work.
You could also add another socket to your broker, have one socket to send to the receiver and one to receive from the processors.
Or, you could replace your DEALER
socket on your broker with another ROUTER
socket, which will allow you to directly address the receiver socket every time.
Follow up, to address the question in your comment:
Each of your workers having a different responsibility is a good reason to replace the DEALER
socket on your broker with a ROUTER
socket.
My off-the-shelf recommendation is to rearchitect around the Majordomo Protocol (later version can be found here, and talked about in the ZMQ guide here, with Java code samples). It does exactly what you seem to be looking for, and does it well.
But, at a simpler level, what you'll be doing is the following:
ROUTER
sockets on both the front and back ends - both of these sockets are bind()
-ed.connect()
your workers do your broker.All of that is what the Majordomo Protocol implements, complete with other necessary elements like heartbeating that make a fully fleshed out ZMQ application. That's why I recommend you go straight to that protocol, if it serves the needs you're trying to accomplish, rather than trying to build your own.