ZeroMQ PUB-SUB通信:SUB什么也没收到

时间:2019-12-10 16:57:05

标签: c++ python-3.x zeromq

我正在尝试在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发送消息却没有错误。实际上,它返回已发送消息的长度。

注意:

  • 睡眠正在试用,以便能够在PUB发送之前启动SUB。但是,如果我删除它并首先启动SUB,我的行为将相同。
  • 如果执行以下操作,它将打印none
Err = socket.connect("tcp://localhost:5556")
print(Err)

我是ZeroMQ的新手,我真的不知道从哪里开始解决这个问题。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

  

Q 有什么想法吗?

如果一个人从未使用过ZeroMQ,
在深入了解更多细节之前,可以先看看"ZeroMQ Principles in less than Five Seconds"


< / p>

步骤-1: repair your side code,以便同时定义 j fValue ,并在 break 条件下验证其正确用法,以避免立即使用 break < / strong>-从发送循环中退出。

第0步:(位于侧,使用 {{1]将ZeroMQ SUB 设置为首先订阅任何主题}} -作为主题过滤器的显式设置的字符串。 如果可行:您的问题被隔离到正确的主题设置中,可以进行实际的主题过滤。 如果不是::您似乎还存在视线“可见性”问题(当不在同一 "" 上时可能会发生(是的,这有时也会在这里发生))。

答案 1 :(得分:0)

我没有快速的方法来检查您的工作,但是我可以给您一些基本的提示,这些提示可能会帮助您解决问题。

  1. 我建议您开始在接收器侧卸下过滤器。为此,您必须将setsockopt替换为socket.setsockopt_string(zmq.SUBSCRIBE, "")

  2. 此外,总是在接收方,我建议您仅打印接收的内容,而不对数据做任何假设,因此,我将所有内容替换为简单的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看到消息。