似乎XPUB / XSUB套接字类型存在严重缺陷,难以解决:
这是我对该中心节点的实现:
#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
,这真的很糟糕。
为什么没有这个问题?有没有已知的解决方法?我的所有谷歌查询都只是指向我的指南...
答案 0 :(得分:1)
我找到了一个解决方法here,即在发布方使用PUSH / PULL,在订阅方使用PUB / SUB。新拓扑看起来像这样:
这是中心节点所需的代码:
#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情况下,发布者从不会看到订阅信息。最坏的情况是订户的订阅,这意味着他们只需要来自一个发布者的数据。所有发布者仍将其数据发送到代理,并且代理将过滤除一个发布者的邮件以外的所有内容。