[zeromq-dev] bidirectional communication howto?
Martin Sustrik
sustrik at fastmq.com
Thu Mar 12 15:41:34 CET 2009
Hi,
> How is bi-directional communication usually achieved in ZeroMQ? For
> example, suppose I have a single server process and multiple client
> processes connected to the server. One option is for the server to
> create a global exchange (for pushing messages to clients) and a
> global queue (for receiving messages from clients). Is this something
> that is typically done? Or is it more common for both ends of the
> connection to create two exchanges (one global, one local) and two
> queues (global, local) ... for a total of 8 exchanges/queues for each
> bidirectional communication channel?
>
> One issue is that anytime a you create a local ZeroMQ object and try
> to bind it to a global object, there is a possibility that the global
> object will be unavailable which causes ZeroMQ to immediately assert
> and fail. Currently I avoid this problem by ensuring that critical
> processes (such as a server process) only declare global objects, and
> leave the "dangerous" binding step to the client process.
Yes, that's the right way to do the thing.
> So essentially I am trying to understand when to use global objects
> and when to use local objects. The v0.3 whitepaper mentions that:
>
> * Message producing application creates an exchange.
> * Message consuming application creates a queue.
> * One of the applications establishes a binding between the
> exchange and the queue.
> * Message producing application sends messages to the exchange.
> * Message consuming application retrieves messages from the queue.
>
> But what about the local versus global issue? Also, it says "one of
> the applications establishes a binding" but how does one decide which
> application should establish the binding?
Ok, I think this have been discussed on the mailing list before, but
I'll summarise the status quo once again:
What you describe is AFAIU a "request/reply" scenario (see picture):
1. There are "services"
2. There are clients of services
3. Each service has a globally unique name (mostly human-readable names
like "process-invoice" or whatever).
4. Each client has a globally unique name, however, given that there can
be possibly infinite number of clients running, the name shoudl be
generated (GUID would work OK).
6. Client creates a local "request exchange" and binds it to the
service's global "request queue"
5. Client creates a local "reply queue" and binds it to the service's
global "reply exchange"
6. When client wants to invoke the service is sends a message to the
request exchange. The message should contain a "reply-to" field, which
is the unique name of the client issuing the request.
7. Service reads messages from its request queue, processes them and
generates replies. Each reply is tagged by the reply-to field taken from
the original request. It then sends replies to its reply exchange.
8. Client application reads replies from its reply queue and discard
those that are tagged with client IDs different from the ID of the client.
That's it.
As you may have noticed there is a performance problem with the design:
Each reply is sent to _all_ the clients rather then only to the
appropriate one. As the message is discarded on all but one client the
behaviour of the system is OK, however, there's excess network traffic.
Messaging systems in general support the concept of "routing" which
means that the message is sent _only_ to those clients that are
interested in it.
This feature is not yet implemented in 0MQ. Our current customers are
focused on different use cases (distributed applications) and thus the
feature is not critical at the moment - my estimate is that it would get
into mainline in couple of months.
Hope this helps.
Martin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: reqrep.png
Type: image/png
Size: 19311 bytes
Desc: not available
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20090312/70bc6d0d/attachment.png>
More information about the zeromq-dev
mailing list