ZeroMQ XPUB / XSUB严重缺陷?

时间:2017-03-30 22:58:57

标签: c++ zeromq

似乎XPUB / XSUB套接字类型存在严重缺陷,难以解决:

XPUBSUB

这是我对该中心节点的实现:

#include <zmq.hpp>

int main()
{
    zmq::context_t context(1);

    //Incoming publications come here
    zmq::socket_t sub(context, ZMQ_XSUB);
    sub.bind("ipc://subscriber.ipc");

    //Outgoing publications go out through here.
    zmq::socket_t pub(context, ZMQ_XPUB);
    pub.bind("ipc://publisher.ipc");

    zmq::proxy(sub, pub, nullptr);

    return 0;
}

问题当然是缓慢的木匠综合症。如果我将新发布者连接到XSUB并发布一些消息,它们就会消失在虚空中:

#include "zhelpers.hpp"

int main () {
    //  Prepare our context and publisher
    zmq::context_t context(1);
    zmq::socket_t publisher(context, ZMQ_PUB);
    publisher.connect("ipc://subscriber.ipc");

    s_sendmore (publisher, "B");
    s_send (publisher, "Disappears into the void!!");

    return 0;
}

但是,如果我在连接到XSUB后sleep(1),它就会神奇地起作用:

#include "zhelpers.hpp"

int main () {
    //  Prepare our context and publisher
    zmq::context_t context(1);
    zmq::socket_t publisher(context, ZMQ_PUB);
    publisher.connect("ipc://subscriber.ipc");

    sleep(1);
    s_sendmore (publisher, "B");
    s_send (publisher, "Magically works!!");

    return 0;
}

指南声称这种“慢加入者”综合症有一个简单的解决方案,但从未提供有效的XSUB / XPUB同步实施。经过大量搜索,看起来大多数人只是sleep,这真的很糟糕。

为什么没有这个问题?有没有已知的解决方法?我的所有谷歌查询都只是指向我的指南...

2 个答案:

答案 0 :(得分:1)

我找到了一个解决方法here,即在发布方使用PUSH / PULL,在订阅方使用PUB / SUB。新拓扑看起来像这样:

pullpub

这是中心节点所需的代码:

#include <zmq.hpp>

int main()
{
    zmq::context_t context(1);

    //Incoming publications come here
    zmq::socket_t sub(context, ZMQ_PULL);
    sub.bind("ipc://subscriber.ipc");

    //Outgoing publications go out through here.
    zmq::socket_t pub(context, ZMQ_PUB);
    pub.bind("ipc://publisher.ipc");

    zmq::proxy(sub, pub, nullptr);

    return 0;
}

然后是发布商:

#include "zhelpers.hpp"

int main () {
    //  Prepare our context and publisher
    zmq::context_t context(1);
    zmq::socket_t publisher(context, ZMQ_PUSH);
    publisher.connect("ipc://subscriber.ipc");

    s_sendmore (publisher, "B");
    s_send (publisher, "No sleep!");

    return 0;
}

这个解决方案似乎工作得相当好,我希望如果他们看到任何不利因素,人们就会加入。如果我遇到更好的答案,我会在这里发帖。

答案 1 :(得分:1)

不利之处是您的发布者一直在发布。在XSUB / XPUB情况下,订阅将转发到您的发布者,以便他们可以限制将其发送到代理的内容。这样可以减少网络流量,减少代理工作。在PULL / PUB情况下,发布者从不会看到订阅信息。最坏的情况是订户的订阅,这意味着他们只需要来自一个发布者的数据。所有发布者仍将其数据发送到代理,并且代理将过滤除一个发布者的邮件以外的所有内容。