Yves
Yves

Reputation: 12371

zeroMQ: zmq_recv() doesn't work

I am using zeroMQ to realize the send-recv message. I use this pattern: PUB-SUB.
However, it seems that I can send some message from the publisher but I couldn't receive it from the subscriber. Here is my code:

//subscriber:

int main(int argc, char** argv){
    void * context = zmq_ctx_new();
    void * subscriber = zmq_socket(context, ZMQ_SUB);
    zmq_connect(subscriber, "tcp:://127.0.0.1:5556");
    const int SIZE = 20;
    char msg[SIZE];
    cout<<"receiving..."<<endl;
    cout<<zmq_recv(subscriber, msg, SIZE, 0)<<endl;
    cout<<"received";
    zmq_close(subscriber);
    zmq_ctx_destroy(context);
    return 0;
}

//publisher:

int main(int argc, char** argv){
    void * context = zmq_ctx_new();
    void * publisher = zmq_socket(context, ZMQ_PUB);
    zmq_bind(publisher, "tcp://127.0.0.1:5556");
    srandom((unsigned)time(NULL));
    char updateMsg[20] = "hello world";
    while(1)
    {
        cin.get();
        cout<<"sending..."<<endl;
        cout<<zmq_send(publisher, updateMsg, 20, 0)<<endl;
        cout<<"sent"<<endl;
    }
    zmq_close(publisher);
    zmq_ctx_destroy(context);
    return 0;
}

Now, I run the publisher then I run the subscriber.
Then I type "Enter" at the publisher and it says:

sending...
20
sent<l

BUT, at the subscriber, it always shows only this line: receiving...
It seems that zmq_recv() is blocked.

Could you please help me?

Upvotes: 0

Views: 2018

Answers (3)

user3666197
user3666197

Reputation: 1

A: ZeroMQ does work.

Your code is OK,

while you have missed a conceptually important point in PUB-SUB design

Yes, ZeroMQ does work well. Yes, your code is OK, so where is the trouble?

The PUB-SUB Formal Communication Pattern has been designed so that PUB/publisher-side distributes each and every message just to those SUB/subscriber-side(s), that have presented themselves to the PUB their individual will-to-receive something. This is being done by so called subscription ( so natural in our human world -- you do not receive any newspapers you have not subscribed to and you may receive some of the papers, you have ).

The ZeroMQ design mirrors this natural pattern.

A "new"-SUB is assumed as not ( implicitly ) subscribed to anything.

Any SUB may subscribe to receive just messages that meet a specified "subscription".

Any SUB may subscribe to receive "everything".

So your code was running as declared - both on the PUB side ( sending nothing to an active SUB side, that just has not yet presented any will to receive something, that thus receives nothing at all, still sitting in a [blocking] waiting-state ).

Nota bene: you might benefit a lot from an excellent book from Pieter HINTJENS -- "Code Connected, Volume 1" (available in PDF), where Pieter spends a lot of time explaining conceptual thinking behind this great, smart, scaleable, nonblocking messaging library. Definitely worth spend a few weeks on his text ( not the code-snippets, but the stories hidden there ). A marvelous book, indeed.

Upvotes: 1

Yves
Yves

Reputation: 12371

For the PUB-SUB pattern, we MUST use setsockopt to set a filter for the subscriber. Otherwise, the subscriber can't receive ANY message. So for this case, what we should do is to add the code below for the subscriber before the zmq_recv: zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "hello", strlen("hello"));

Upvotes: 1

Marcus M&#252;ller
Marcus M&#252;ller

Reputation: 36337

http://zguide.zeromq.org/php:chapter5#Pros-and-Cons-of-Pub-Sub

says:

Publishers can't tell when subscribers are successfully connected, both on initial connections, and on reconnections after network failures.

The point here is that your publisher is started first, sends its messages into the void, as fast as possible to your hardware.

In the meantime, your subscriber fails, because your URL contains one : too many, or something else:

zmq_connect(subscriber, "tcp:://127.0.0.1:5556");

so here you go: an infinite amount of messages being sent nowhere, and failed subscriber that doesn't tell you it's failed, as well as a publisher not noticing the receiving end hasn't successfully connected.

Upvotes: 1

Related Questions