【问题标题】:ZeroMQ PUB-SUB communication : SUB receives nothingZeroMQ PUB-SUB 通信:SUB 什么也没收到
【发布时间】:2020-04-03 22:18:01
【问题描述】:

我正在尝试在 ZeroMQ 中进行 PUB-SUB 通信,其中 PUB 在 C++ 中,SUB 在 python 中。我正在使用 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 发送消息时没有错误。实际上,它返回已发送消息的长度。

注意事项:

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

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

【问题讨论】:

  • 为引用所有发行版本添加了 +1。包括 ZeroMQ - 软件工程工艺的良好标志

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


【解决方案1】:

感谢大家的回答。我发现这是一个经典的“慢木匠”问题。我在循环之前移动了 Sleep(10) 以查看发生了什么并且它起作用了。

在我的第一条消息中不清楚的是(因为我的代码过度清理以使其在此处清楚)是 fValue 设置为一个数字以在循环中具有确定的交互次数,或者设置为 0 以无限循环。所以,我将它设置为 3 只是为了发送一些消息,但是 PUB 没有足够的时间连接到 SUB 以便 SUB 看到消息。

【讨论】:

    【解决方案2】:

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

    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)
    

    通过这种方式,您可以了解真正通过套接字发送的内容(如果有的话)。

    如果收到了一些东西,但它不是您所期望的,那么您可以在发送方工作。例如,您可以查看socket.send()ZMQ_SNDMORE 标志,它允许您创建多部分消息。 (有关“主题过滤”的工作原理,请参阅文档here)。

    如果你还需要帮助,明天我可能会更彻底地看一下。

    【讨论】:

      【解决方案3】:

      有什么想法吗?

      如果您从未使用过 ZeroMQ,
      您可以在这里先查看"ZeroMQ Principles in less than Five Seconds",然后再深入了解更多细节


      步骤-1: repair your side code ,以便正确定义jfValue 并验证其在 break 条件下的正确用法,以避免立即从发送循环中退出 break

      步骤 0: 端,设置 ZeroMQ SUB 以首先订阅任何主题,使用 "" - 作为主题过滤器的显式设置的字符串。 如果可行:您的问题与实际执行主题过滤的正确主题设置有关。 如果不是:您似乎也有视线“可见性”问题(当不在同一个位置时可能会发生这种情况localhost(是的,这也有时在这里发生))。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-11
        • 1970-01-01
        • 2015-04-21
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多