Python使用Paho MQTT出现ConnectionError未定义错误求助
我用以下代码通过WebSocket+SSL连接带密码验证的MQTT broker:
import paho.mqtt.client as mqtt import ssl import time def on_connect(client, userdata, flags, rc): print("connected with result code "+str(rc)) def on_publish(client, userdata, mid): print("mid: "+str(mid)) client = mqtt.Client('device', transport="websockets") client.on_connect = on_connect client.on_publish = on_publish client.username_pw_set("login", "pass") client.ws_set_options(path="/logger") client.tls_set(ca_certs=None, certfile=None, keyfile=None, cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS, ciphers=None) connection = False print("Trying to connect ...") client.connect(host="mqtt.broker.io", port=443) connection = True for _ in range(5): time.sleep(1) client.publish("some/topic", "HELLO", qos=2) client.loop(1) client.disconnect()
运行时抛出以下错误:
Trying to connect ... connected with result code 0 Traceback (most
recent call last): File
"/home/souvik/GitLab/Embedded/demo_mqtt_auth.py", line 30, in
client.loop(1) File "/home/souvik/.local/lib/python2.7/site-packages/paho/mqtt/client.py",
line 1120, in loop
return self._loop(timeout) File "/home/souvik/.local/lib/python2.7/site-packages/paho/mqtt/client.py",
line 1164, in _loop
rc = self.loop_read() File "/home/souvik/.local/lib/python2.7/site-packages/paho/mqtt/client.py",
line 1556, in loop_read
rc = self._packet_read() File "/home/souvik/.local/lib/python2.7/site-packages/paho/mqtt/client.py",
line 2373, in _packet_read
except ConnectionError as err: NameError: global name 'ConnectionError' is not defined
sleepiz_one on hw-1929-diagnostics [$!] on (eu-west-1) took 6s ❯
/bin/python /home/souvik/GitLab/Embedded/demo_mqtt_auth.py Trying to
connect ... connected with result code 0 Traceback (most recent call
last): File "/home/souvik/GitLab/Embedded/demo_mqtt_auth.py", line
30, in
client.loop(1) File "/home/souvik/.local/lib/python2.7/site-packages/paho/mqtt/client.py",
line 1120, in loop
return self._loop(timeout) File "/home/souvik/.local/lib/python2.7/site-packages/paho/mqtt/client.py",
line 1164, in _loop
rc = self.loop_read() File "/home/souvik/.local/lib/python2.7/site-packages/paho/mqtt/client.py",
line 1556, in loop_read
rc = self._packet_read() File "/home/souvik/.local/lib/python2.7/site-packages/paho/mqtt/client.py",
line 2373, in _packet_read
except ConnectionError as err: NameError: global name 'ConnectionError' is not defined
虽然抛出异常,但数据已经成功发送到broker。补充信息:使用paho-mqtt 1.6.1版本,Python版本为2.7。
这个错误的核心原因是Python 2.7没有ConnectionError这个内置异常类,它是Python 3.3及以上版本才新增的。而你用的paho-mqtt 1.6.1源码里直接引用了这个Python 2.7不存在的异常,所以触发了NameError。
有两种可行的解决方式:
- 升级Python版本:直接切换到Python 3.3+,从根源上解决兼容性问题,这也是长期来看最稳妥的方案。
- 修改paho-mqtt源码:如果必须保留Python 2.7,找到本地安装的paho-mqtt包中的
client.py文件(路径为/home/souvik/.local/lib/python2.7/site-packages/paho/mqtt/client.py),定位到第2373行的except ConnectionError as err:,替换为Python 2.7兼容的异常捕获逻辑:
因为Python 2.7中,网络连接相关错误会抛出except (IOError, OSError) as err:IOError或OSError,替换后就能正常捕获异常,不会再触发NameError。
另外,你的代码可以优化一下消息循环的写法,用loop_start()启动后台循环,避免每次publish后手动调用loop(1),代码会更简洁稳定:
print("Trying to connect ...") client.connect(host="mqtt.broker.io", port=443) client.loop_start() # 启动后台消息循环 for _ in range(5): time.sleep(1) client.publish("some/topic", "HELLO", qos=2) time.sleep(2) # 等待QoS2消息的确认流程完成 client.loop_stop() client.disconnect()
内容的提问来源于stack exchange,提问作者Souvik Saha

