Paho-MQTT连接每90秒断开,协议版本遭拒问题求助
问题描述
使用Python的paho-mqtt库编写温度传感器数据上报脚本,数据能按预期每15分钟发布,但日志显示MQTT连接每隔约90秒意外断开,尽管已将keepalive值设置为930秒(15分30秒)。日志报错如下:
INFO:root:Unexpected disconnection. Reason: Connection Refused: unacceptable protocol version.
脚本代码
import paho.mqtt.client as mqtt import Adafruit_DHT import time import ssl import logging logging.basicConfig(level=logging.DEBUG, filename='/home/pi/Documents/mqtt.log', encoding='utf-8') # Set up DHT22 sensor dht_sensor = Adafruit_DHT.DHT22 dht_pin = 4 # GPIO pin number the sensor is connected to username = 'master:mqttuser_karlsruhe' secret = 'ifYsftrjtzktzkfDSc' host = '192.168.0.52' port = 8883 clientID = 'raspi_ka' assetID = '3ndhrtjtz55rrGa' def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) logging.info("Connected with result code "+str(rc)) def on_publish(client, userdata, msg): print(msg.topic+" "+str(msg.payload)) logging.info(msg.topic+" "+str(msg.payload)) def on_disconnect(client, userdata, rc): if rc != 0: print("Unexpected disconnection.") logging.info(f"Unexpected disconnection. Reason: {mqtt.connack_string(rc)}") def on_log(client, userdata, level, buf): print("log: ", buf) logging.info("log: ", buf) mqtt_client = mqtt.Client(clientID) mqtt_client.username_pw_set(username, password=secret) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) mqtt_client.tls_set_context(context) mqtt_client.on_connect = on_connect mqtt_client.on_disconnect = on_disconnect mqtt_client.on_publish = on_publish mqtt_client.on_log = on_log mqtt_client.connect(host, port=port, keepalive=930) mqtt_client.loop_start() # Continuously read and send temperature values while True: humidity, temperature = Adafruit_DHT.read_retry(dht_sensor, dht_pin) if humidity is not None and temperature is not None: mqtt_client.publish(f"master/{clientID}/writeattributevalue/temperature/{assetID}", temperature) mqtt_client.publish(f"master/{clientID}/writeattributevalue/humidity/{assetID}", humidity) else: print("Failed to read temperature sensor data") print(temperature) print("") time.sleep(900) # Disconnect MQTT client mqtt_client.disconnect() mqtt_client.loop_stop()
问题原因与解决方法
核心原因
报错Connection Refused: unacceptable protocol version明确指向客户端与MQTT服务器的协议版本不匹配。paho-mqtt库的mqtt.Client()默认使用MQTT 3.1版本,而多数现代MQTT服务器(如Mosquitto、EMQX)默认仅支持MQTT 3.1.1或更高版本(如5.0),导致连接被服务器拒绝,进而触发重复重连-断开的循环。
解决步骤
指定兼容的MQTT协议版本
在创建Client实例时,显式指定服务器支持的协议版本,推荐使用MQTT 3.1.1:# 替换原创建Client的代码,指定MQTT 3.1.1协议 mqtt_client = mqtt.Client(clientID, protocol=mqtt.MQTTv311)若服务器支持MQTT 5.0,也可使用
protocol=mqtt.MQTTv5。验证服务器协议支持
检查MQTT服务器的配置文件,确认其允许的协议版本。例如Mosquitto的配置中,protocol字段可设置为mqtt(默认支持3.1.1)或明确指定版本。额外注意点
脚本中loop_start()已开启后台线程处理MQTT网络事件(包括心跳),time.sleep(900)的阻塞逻辑本身不会导致连接问题,解决协议版本匹配后,keepalive设置即可正常生效。
内容的提问来源于stack exchange,提问作者deputy-chief-hardy

