我看到了使用的奇怪行为ZMQ_PUB。
我有一个生产.connect()-s不同工艺
是.bind()在ZMQ_SUB插座上。
全部订阅者.bind(),发布者.connect()-s。
当生产者启动时,它会创建一个ZMQ_PUB套接字并将其.connect()-s连接到不同的进程。然后,它立即开始定期发送消息。
如预期的那样,如果没有连接的订户,它将丢弃所有消息,直到订户启动。
该流正常工作,然后,当订户启动时,它会从那一刻开始接收消息。
现在,问题是:
因此,我看到的是生产者在订户关闭时将所有消息排队。一旦套接字重新连接,由于订户进程重新启动,它将发送所有排队的消息。
从这里我了解到,发布者应该在没有连接的订阅者的情况下丢弃所有已发送的消息:
ZeroMQ示例
“发布者没有连接的订阅者,那么它只会丢弃所有消息。”
为什么会这样呢?
顺便说一下,我正在Linux上使用C ++进行这些测试。
绑定时,我尝试在订户上设置一个不同的身份,但是没有用。发布者仍然排队消息,并在订阅者重新启动时将其全部传递。
提前致谢,
路易斯
更新:
重要更新!!!!
在发布此问题之前,
我尝试了不同的解决方案。一种是设置ZMQ_LINGER为0,这是行不通的。
我添加了ZMQ:IMMEDIATE,它起作用了,但是我发现ZMQ:IMMEDIATE仅此一项是行不通的。它也需要ZMQ_LINGER。
Luis Rojas 3小时前
更新: 根据请求,我正在添加一些简单的测试用例来说明我的观点。一个是简单的订户,它在命令行上运行并接收uri绑定的位置,例如:
$ ./sub tcp://127.0.0.1:50001
另一个是发布者,例如,它接收要连接的uri列表:
./pub tcp://127.0.0.1:50001 tcp://127.0.0.1:50002
订户接收多达5条消息,然后关闭套接字并退出。我们可以在wireshark上看到两种方式的FIN / ACK交换,以及套接字如何移动到TIME_WAIT状态。然后,发布者开始发送SYN,尝试重新连接(探测ZMQ_PUB知道连接已关闭)
我明确地没有取消订阅套接字,只是关闭了它。我认为,如果套接字关闭,则发布者应自动终止对该连接的任何订阅。
因此,我看到的是:启动订户(一个或多个),启动发布者,然后开始发送消息。订户收到5条消息并结束。同时,发布者继续发送消息,而没有连接订户。我重新启动订阅服务器,并立即收到几条消息,因为它们在发布者端排队。我认为这些排队的消息打破了发布/订阅模型,在该模型中,消息应仅传递给已连接的订户。如果授权方关闭了连接,则应丢弃发给该订户的消息。更重要的是,当订户重新启动时,它可能会决定订阅其他消息,但仍将接收由绑定在同一端口的“先前的化身”订阅的消息。
我的建议是ZMQ_PUB(处于连接模式)在检测到套接字断开连接时,应清除该套接字上的所有订阅,直到它重新连接并且NEW订阅者决定重新订阅为止。
对于语言错误,我深表歉意,但英语不是我的母语。
酒馆的代码:
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h> …Run Code Online (Sandbox Code Playgroud) zeromq ×1