Paho обновляет пользовательские данные из обратного вызова on_message

#python #callback #global-variables #paho #user-data

#python #обратный вызов #глобальные переменные #paho #пользовательские данные

Вопрос:

В принципе, я хочу, чтобы мои пользовательские данные действовали как глобальный флаг, который считывается и обновляется между последовательными выполнением on_message() обратного вызова. Я написал и запустил следующий скрипт:

 import paho.mqtt.client as mqtt
MQTT_SERVER = "broker.hivemq.com"
MQTT_TOPIC = "IvanHu"

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " str(rc))
    client.subscribe(MQTT_TOPIC)
    
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(userdata, end = '')
    print(" message received.")
    userdata  = 1
    user_data_set(client_userdata)

client_userdata = 1

client = mqtt.Client(userdata=client_userdata)
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_SERVER, 1883, 60)

client.loop_forever()
  

Затем я опубликовал тему IvanHu 4 раза. Я ожидаю, что результат моего скрипта python paho будет следующим:

 Connected with result code 0
1 message received.
2 message received.
3 message received.
4 message received.
  

Однако это было то, что я получил вместо этого:

 Connected with result code 0
1 message received.
1 message received.
1 message received.
1 message received.
  

Очевидно, что переменная client_userdata никогда не обновлялась в последовательных вызовах on_message(). Как правильно обновить эту переменную?

Комментарии:

1. Похоже, что userdata увеличивается в on_message функции, но больше никогда не используется: вы передаете client_userdata переменную (которая всегда равна 1 ) user_data_set функции.

Ответ №1:

Вы должны указать начальное значение для пользовательских данных client.user_data_set перед подключением, затем вы можете обновить пользовательские данные в on_message обратном вызове.

 import paho.mqtt.client as mqtt
MQTT_SERVER = "broker.hivemq.com"
MQTT_TOPIC = "IvanHu"

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " str(rc))
    client.subscribe(MQTT_TOPIC)
    
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(userdata, end = '')
    print(" message received.")
    user_data_set(userdata   1)    # <-- Update userdata

client_userdata = 1

client = mqtt.Client(userdata=client_userdata)
client.on_connect = on_connect
client.on_message = on_message
client.user_data_set(1)    # <-- Initialize
client.connect(MQTT_SERVER, 1883, 60)

client.loop_forever()
  

Ответ №2:

Я не смог найти способ удовлетворить мои требования, используя подход userdata, но я смог сделать это с помощью подхода глобальных переменных. Вот рабочий сценарий:

 import paho.mqtt.client as mqtt
MQTT_SERVER = "broker.hivemq.com"
MQTT_TOPIC = "IvanHu"

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " str(rc))
    client.subscribe(MQTT_TOPIC)
    
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    global client_userdata
    print(client_userdata, end = '')
    print(" message received.")
    client_userdata  = 1

client_userdata = 1

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_SERVER, 1883, 60)

client.loop_forever()
  

Вывод:

 Connected with result code 0
1 message received.
2 message received.
3 message received.
4 message received.
  

Ответ №3:

Похоже, вы пропустили бит в документах, в котором говорится об обновлении user_data объекта

Он может быть обновлен на более позднем этапе с помощью функции user_data_set().

Взято из документов здесь

Это означает, что вам нужно передать новое значение в set_userdata() , поэтому оно должно быть следующим:

 # The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(userdata, end = '')
    print(" message received.")
    userdata  = 1
    client.user_data_set(userdata)
  

Комментарии:

1. к сожалению, изменение user_data_set(client_userdata) на user_data_set(userdata) не изменило результат. Все еще 1 message received. четыре раза. Я действительно попробовал ваше предложение прошлой ночью и повторно подтвердил его сегодня утром.

2. Извините, опечатка. Это должно быть client.user_data_set(user_dara)