【问题标题】:paho-mqtt won't give me the queued messagespaho-mqtt 不会给我排队的消息
【发布时间】:2020-12-17 19:59:59
【问题描述】:

使用 paho-mqtt 并尝试让它接收排队的消息。我使用的代理是 emqx 4.2.2,这是我的脚本:

from paho.mqtt.client import Client, MQTTv5


def on_connect(mqttc, obj, flags, rc, other):
    print("    Session present: " + str(flags['session present']))
    print("    Connection result: " + str(rc))
    mqttc.subscribe([
        ('/message/1', 1)
    ])


def on_message(*args, **kwargs):
    print("received a message")


client = Client(
    client_id='test-client-id',
    protocol=MQTTv5,
)


client.username_pw_set(
    username="test-user-2",
    password="test"
)

client.on_connect = on_connect
client.on_message = on_message

client.connect(
    host='localhost',
    port=1883,
    keepalive=60,
    clean_start=False,
)

client.loop_forever()

我现在去向代理发布一条消息:

mosquitto_pub -u test-user-2 -P test -t '/message/1' -m 'this is a message' -q 1 -V mqttv5

当客户端连接到代理时,它确实会收到消息,但鉴于我是 使用 QoS 1 订阅并且使用 QoS 1 发布消息我希望如果我 断开我的客户端与代理的​​连接,然后向该主题发布更多 QoS 1 消息,然后使用相同的固定 client_id 将我的客户端重新连接到代理,然后我的客户端将收到我的客户端不在时已排队的消息。好吧,这并没有发生,并且使用带有 -c 标志的 mosquitto_sub 模拟相同的功能一切都按预期工作,这让我问自己...... paho-mqtt 有问题吗?我做错了吗?

【问题讨论】:

    标签: python mqtt paho emq


    【解决方案1】:

    在 MQTT v5 中,干净启动仅表示会话是否在启动时被删除。要控制断开连接后会话持续多长时间,您需要设置会话到期间隔:

    import paho.mqtt.properties as properties
    ...
    connect_properties = properties.Properties(properties.PacketTypes.CONNECT)
    connect_properties.SessionExpiryInterval = 3600
    
    client.connect("localhost", 1883, 60, properties=connect_properties)
    

    【讨论】:

      【解决方案2】:

      QOS 仅在客户端订阅时才有效...如果您想在订阅之前接收消息,您需要发布设置了保留标志的消息...然后您只会收到最后一条发送的消息。如果你真的需要获取多条消息,那么你需要使用 AMQ 之类的东西,而不是 MQTT。

      【讨论】:

      • 感谢您的回复。也许我没有清楚地描述我的过程。首先,我将我的 paho 客户端连接到交换器,我使用 QoS 1 订阅了一些主题,然后断开 paho 与交换器的连接。当客户端断开连接时,我发布了一些上述主题会收到的内容,也使用 QoS 1。这应该为 paho 客户端排队,直到客户端重新连接。如果我使用 mosquitto_pub 和 mosquitto_sub cli 工具,它确实有效。只有 paho 客户端似乎看不到它离开时发布的消息。
      【解决方案3】:

      它应该是clean_session 而不是clean_start,它需要传递给Client 构造函数而不是connect() 函数:

      ...
      client = Client(
          client_id='test-client-id',
          protocol=MQTTv5,
          clean_session=False
      )
      
      
      client.username_pw_set(
          username="test-user-2",
          password="test"
      )
      
      client.on_connect = on_connect
      client.on_message = on_message
      
      client.connect(
          host='localhost',
          port=1883,
          keepalive=60
      )
      ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-17
        相关资源
        最近更新 更多