我正在尝试在ZeroMQ中获得PUB-SUB通信,其中PUB在C ++中,而SUB在python中。我正在使用python 3.8,ZeroMQ 4.3.2,pyzmq 18.1.1和cppzmq 4.5.0
PUB:
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++;
}
}
SUB:
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的新手,我真的不知道从哪里开始解决这个问题。有什么想法吗?
答案 0 :(得分:1)
Q :有什么想法吗?
如果一个人从未使用过ZeroMQ,
在深入了解更多细节之前,可以先看看"ZeroMQ Principles in less than Five Seconds"
< / p>
步骤-1: repair your c++ side code,以便同时定义 j
和 fValue
,并在 break
条件下验证其正确用法,以避免立即使用 break
< / strong>-从发送循环中退出。
第0步:(位于python侧,使用 {{1]将ZeroMQ SUB
设置为首先订阅任何主题}} -作为主题过滤器的显式设置的字符串。 如果可行:您的问题被隔离到正确的主题设置中,可以进行实际的主题过滤。 如果不是::您似乎还存在视线“可见性”问题(当不在同一 ""
上时可能会发生(是的,这有时也会在这里发生))。
答案 1 :(得分:0)
我没有快速的方法来检查您的工作,但是我可以给您一些基本的提示,这些提示可能会帮助您解决问题。
我建议您开始在接收器侧卸下过滤器。为此,您必须将setsockopt
替换为socket.setsockopt_string(zmq.SUBSCRIBE, "")
此外,总是在接收方,我建议您仅打印接收的内容,而不对数据做任何假设,因此,我将所有内容替换为简单的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)
通过这种方式,您可以真正了解通过套接字发送的内容(如果有的话)。
如果收到了某些东西,但不是您所期望的,则可以在发件人一方工作。例如,您可以查看ZMQ_SNDMORE
的{{1}}标志,它允许您创建多部分消息。 (有关“主题过滤”的工作原理,请参见文档here。
如果您仍然需要帮助,明天我可能会更彻底地进行研究。
答案 2 :(得分:0)
感谢大家的回答。我发现这是一个典型的“慢加入者”问题。我将Sleep(10)移到了循环之前,以查看发生了什么并且有效。
我的第一条消息尚不清楚(因为我的代码过度清理,以便在此处清楚说明)是将fValue设置为一个数字以在循环中具有确定的交互次数,或者将其设置为0以无限循环。因此,我将其设置为3只是为了发送少量消息,但是PUB没有足够的时间连接到SUB,以便SUB看到消息。