14

I am facing the following problem:

I have a client (ultimately n-clients) and like to connect to a server. Clients know the server/host address but the server does not know the address of the client(s). I like to be able to accomplish the following messaging patterns between client-server (both, the client and the server need to be able to accomplish the following message patterns):

  • Publish Messages (no reply expected)
  • Receive Messages (no reply expected)
  • Request / Receive Messages (reply expected)
  • Stream messages (this may be redundant as it may be served through the publish message pattern above)

Again the important point, and where I struggle is how to connect to the host while still being able to send AND receive messages. The host has no ability to connect to clients, it can only accept client connection requests. Please note that I do not look for a solution with proxy/broker to which both client and server connect otherwise I could go directly with solutions such as rabbitmq.

How can I best accomplish this, even better with reference to code samples.

Thanks a lot.

Matt
  • 7,004
  • 11
  • 71
  • 117
  • You clearly have not read the ZeroMq guide; these basic questions are answered in just the first section alone with code samples, read it, it will amaze you: http://zguide.zeromq.org/page:all – raffian Jun 08 '13 at 16:24
  • 3
    @Raffian, with all due respect but you may have misread/misunderstood my question. By no means is this question answered in any of the first chapters of the guide. I have no even come across an advanced pattern in the guide that answers this question. I came across some code by someone else on the net who implemented a similar solution than what I am seeking with front and backend on both, server and client side on different tasks and with two sockets each. So it's far from trivial and would appreciate if you could review my question and your downvote. – Matt Jun 09 '13 at 13:42
  • Here is the reference I mentioned: http://www.codebullets.com/a-splendid-new-way-of-tcp-messaging-920. It does not do much aside one-way messaging but it accomplishes duplex messaging. Judge for yourself and pls point me to the pages of your reference something remotely similar is accomplished in the zeromq guide. – Matt Jun 09 '13 at 14:42
  • I don't believe I misread your question, not the first part, at least. You want to do bidirectional pub/sub, the first two bullets on your list, and the server doesn't know the address of the clients (why does that even matter)? This is the dynamic discovery problem illustrated in chapter 2 here http://bit.ly/118L6G7. Just create separate pub/sub sockets for client and server using different ports and use two separate proxies to do forwarding; do the same for request/reply. I can't address streaming. Beyond that, considering rephrasing your question because it's not 100% clear. – raffian Jun 09 '13 at 15:06
  • I'll remove the down vote, but SO won't let me unless you edit the question. – raffian Jun 09 '13 at 15:18
  • @Raffian, risking to repeat myself that is not what the question asked, if I wanted a proxy in the middle and essentially was comfortable with a brokered solution I would go with solutions such as Tipco or rabbitmq.it would entirely defeat the main selling points of zeromq which is P2P messaging capabilities. Please take a look at the link I mentioned in my earlier comment which solves this particular part of my question rather elegantly, something I find nowhere in the zeromq documentation unless I missed it. But I I'll edit my question for clarity. – Matt Jun 09 '13 at 16:47

1 Answers1

15

For connecting to the server, you need a DEALER socket on the client side, and a ROUTER socket on the server. Because you need a publish subscribe pattern you will need a SUB socket on the client side, and a PUB socket on the server side.

  Client       Server
+-------+      +--------+
| Dealer| <--> | Router |
|  Sub  | <--  |  Pub   |
+-------+      +--------+

So you bind the Router and the Pub sockets, and connect the Dealer, and the Sub sockets. Than when you want to:

  • Publish Messages (no reply expected): Create an envelope ( pub, channel, message ) and send it through the Dealer, on the Router side the router will receive the following envelope ( dealer, pub, channel, message ), so you can publish the message on channel through PUB socket.

  • Receive Messages (no reply expected): It's done with the SUB sockets on the client side, and since every publication goes through the ROUTER you can easily implement a subscription mechanism, or just add a SUB socket on the server side, and connect (inproc) to the PUB socket (maybe this is a cleaner solution).

  • Request / Receive Messages (reply expected): It can be done with the Dealer - Router. you just create a different envelope ( req, message ), so your Router ( receive: dealer, req, message ) will know that it should be processed, and can send a reply to the dealer. If your server needs to send requests to the clients, you just need to keep track of the connected clients, and send an envelope (dealer, req, msg), so your dealer can reply with example a ( rep, message ) envelope.

  • Streaming: as you stated it can be done with the publish pattern

This is how I would do it, if you need heart beating, it gets a bit complicated, but not much.

balazs
  • 5,698
  • 7
  • 37
  • 45
  • @belazs, Thanks, just wondering, if I do not care about topic subscriptions can't I just simply get away with a dealer on the client side and router on server side? – Matt Jun 12 '13 at 17:16
  • 1
    @MattWolf Yes, in my example sub is just used for receiving messages from the publisher. I'm glad I could help. – balazs Jun 12 '13 at 17:25