![](/img/trans.png)
[英]How to implement simple ZeroMQ Pub-Sub communication between Python publisher and C++ subscriber?
[英]ZeroMQ PUB-SUB communication : SUB receives nothing
我正在尝试在 ZeroMQ 中获得 PUB-SUB 通信,在 C++ 中的 PUB 和 python 中的 SUB 工作。 我正在使用 python 3.8、ZeroMQ 4.3.2、pyzmq 18.1.1 和 cppzmq 4.5.0
酒馆 :
int main()
{
Sleep(10000);
zmq::context_t context(1);
zmq::socket_t publisher(context, ZMQ_PUB);
publisher.bind("tcp://*:5556");
int zipcode, temperature, relhumidity;
while (true) {
// Get values (first supposed to be random)
zipcode = 10001;
temperature = 27;
relhumidity = 61;
// Send message to the subscriber
zmq::message_t message(20);
snprintf((char *)message.data(), 20, "%05d %d %d", zipcode, temperature, relhumidity);
publisher.send(message, zmq::send_flags::none);
std::fprintf(stderr, "[INFO] Sent data: %i, %i, %i \n", zipcode, temperature, relhumidity);
if (fValue && j >= fValue) {
break;
}
j++;
}
}
子:
import sys
import zmq
# Socket to talk to server
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:5556")
# Subscribe to zipcode, default is NYC, 10001
zip_filter = "10001"
# Python 2 - ascii bytes to unicode str
if isinstance(zip_filter, bytes):
zip_filter = zip_filter.decode('ascii')
socket.setsockopt_string(zmq.SUBSCRIBE, zip_filter)
# Process 5 updates
for update_nbr in range(3):
string = socket.recv_string()
zipcode, temperature, relhumidity = string.split()
print("Received data : %s , %d , %d" % (zip_filter, temperature, relhumidity))
但是我无法让它工作,因为 SUB 在string = socket.recv_string()
上永远等待,而 PUB 发送消息而没有错误。 事实上,它返回发送消息的长度。
注意事项:
none
:Err = socket.connect("tcp://localhost:5556")
print(Err)
我是 ZeroMQ 的新手,我真的不知道从哪里开始解决这个问题。 任何的想法 ?
问:有什么想法吗?
如果从未使用过 ZeroMQ,
在深入了解更多细节之前,您可以在这里先看看“不到五秒的ZeroMQ原则”
步骤-1:修复你的c++端代码,以便正确定义j
和fValue
并验证其在break
正确使用,以避免从发送循环中立即break
。
第 0 步:在python端,设置 ZeroMQ SUB
首先订阅任何主题,使用""
- 作为主题过滤器显式设置的字符串。 如果可行:您的问题与实际进行主题过滤的正确主题设置无关。 如果不是:您似乎也有视线“可见性”问题(当不在同一个localhost
上时可能会发生这种情况(是的,这有时也会发生在这里))。
我没有快速检查你的工作的方法,但我可以给你一些基本的提示,可以让你解决问题。
我建议您开始移除接收器侧的过滤器。 要做到这一点,你必须用socket.setsockopt_string(zmq.SUBSCRIBE, "")
类的东西替换你的setsockopt
此外,总是在接收方,我建议您只打印您收到的内容,而不对数据做任何假设,所以我会用简单的print(socket.recv_string())
替换所有内容(或者甚至只是print(socket.recv())
。
您的简单(调试)接收器将类似于:
import zmq
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:5556")
socket.setsockopt_string(zmq.SUBSCRIBE, "")
data = socket.recv_string()
print(data)
通过这种方式,您可以意识到通过套接字真正发送了什么(以及如果有的话)。
如果收到了一些东西,但不是您所期望的,那么您可以在发送方工作。 例如,您可以查看socket.send()
的ZMQ_SNDMORE
标志,它允许您创建多部分消息。 (有关“主题过滤”的工作原理,请参阅 此处的文档)。
如果您还需要帮助,明天我可能会更彻底地看一下。
感谢大家的回答。 我发现这是一个经典的“慢木工”问题。 我在循环之前移动了 Sleep(10) 以查看会发生什么并且它起作用了。
在我的第一条消息中不清楚的是(因为过度清理了我的代码以在此处明确说明)是 fValue 要么设置为一个数字以在循环中具有确定的交互次数,要么设置为 0 以无限循环。 所以,我将它设置为 3 只是为了发送一些消息,但是 PUB 没有足够的时间连接到 SUB 以便 SUB 看到消息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.