简体   繁体   English

Mqtt 订阅者,loop_forever() 不起作用

[英]Mqtt Subscriber, loop_forever() does not work

I am having an issue with the code below.我对下面的代码有疑问。

The code works perfectly at the beginning.该代码一开始就完美运行。 First it says Connected to MQTT Broker!首先它说Connected to MQTT Broker! and receives data from it.并从中接收数据。 But after a long time (like 6 hours, or 10 hours etc.) it says again Connected to MQTT Broker!但过了很长时间(比如 6 小时或 10 小时等),它再次显示Connected to MQTT Broker! and after that id does not receive any other data.之后 id 不会收到任何其他数据。

I am trying to make this program work forever, but i don't know what i have done wrong.我试图让这个程序永远工作,但我不知道我做错了什么。 Any ideas?有任何想法吗?

#   python3.6

import random
import mysql.connector
from paho.mqtt import client as mqtt_client
import json

#   Code for MQTT Connection
broker = 'YOUR_BROKER'
port = 1883
topic = "YOUR_TOPIC"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 100)}'
username = "THE_USERNAME"
password = "THE_PASSWORD"


#   Function to connect on mqtt
def connect_mqtt() -> mqtt_client:
    def on_connect(client, userdata, flags, rc):
        if rc == 0:
            print("Connected to MQTT Broker!")
        else:
            print("Failed to connect, return code %d\n", rc)

    client = mqtt_client.Client(client_id)
    client.username_pw_set(username, password)
    client.on_connect = on_connect
    client.connect(broker, port)
    return client

#   function to subscribe from mqtt
def subscribeFunc(client: mqtt_client):
    def on_messageFunc(client, userdata, msg):
        print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")

    client.subscribe(topic)
    client.on_message = on_messageFunc


def run():
    client = connect_mqtt()
    subscribeFunc(client)
    client.loop_forever()


if __name__ == '__main__':
    run()

I tried to find the problem but it seems that nothing changed significantly.我试图找出问题所在,但似乎没有任何重大变化。 I am expecting this program to receive data without stopping.我期待这个程序不停地接收数据。

Network connections may not be 100% reliable (and servers etc are restarted from time to time) so expecting the connection to remain up forever is unrealistic.网络连接可能不是 100% 可靠(并且服务器等会不时重新启动),因此期望连接永远保持连接是不现实的。 The issue with your code is that it connects then subscribes;您的代码的问题在于它先连接然后订阅; if the connection is dropped it does not resubscribe.如果连接断开,它不会重新订阅。 As the connection is clean_session=true and subscription qos=0 (the defaults) the broker will forget about any active subscriptions when the connection drops (so the client will reconnect but not receive any more messages).由于连接是clean_session=true和订阅qos=0 (默认值),代理将在连接断开时忘记任何活动订阅(因此客户端将重新连接但不会收到更多消息)。

The Simple solution is to use the approach shown in the docs and subscribe in the on_connect callback (that way the subscription will be renewed after reconnection):简单的解决方案是使用文档中显示的方法并在on_connect回调中订阅(这样订阅将在重新连接后更新):

def on_connect(client, userdata, flags, rc):
    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.subscribe("$SYS/#")

client = mqtt.Client()
client.on_connect = on_connect
client.connect("mqtt.eclipseprojects.io", 1883, 60)

You may also want to consider the advice in this answer (as per the comment from @mnikley) because that way the broker will queue up messages for you while the connection is down (otherwise these will be lost).您可能还想考虑此答案中的建议(根据@mnikley 的评论),因为这样代理会在连接断开时为您排队消息(否则这些消息将丢失)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM