Python3.9使用paho-mqtt连接Ably无CONNACK响应问题咨询
问题根因
连接失败核心是paho-mqtt客户端未启用TLS加密:
- Ably服务的8883端口是MQTTS(TLS加密传输MQTT)专用端口,仅接收完成TLS握手后的加密MQTT报文
- 可正常运行的NodeJS示例中连接地址使用
mqtts协议前缀,mqtt.js库会自动识别该前缀启用TLS配置,因此连接流程正常 - paho-mqtt默认
connect()方法走明文TCP传输,你当前代码直接将明文CONNECT报文发送到要求TLS加密的8883端口,服务端收到不符合协议规范的明文流量会直接丢弃,不返回任何响应,客户端等待CONNACK超时后就会重发CONNECT报文,和你看到的循环发CONNECT的日志表现完全匹配 - 你测试连接HiveMQ时使用的是1883端口,这是明文MQTT的默认端口,不需要加密即可通信,因此能正常收到CONNACK,这也印证了TLS配置缺失的问题
修复方案
在调用connect()方法前,为客户端添加TLS配置即可,其余业务逻辑不需要改动:
- 导入Python内置的
ssl模块 - 调用客户端的
tls_set()方法启用TLS,默认使用系统信任的CA证书校验服务端证书即可,不需要额外申请客户端证书 - 顺便修正你原代码第一行的笔误:
mport os应为import os
修正后可正常运行的代码
import os import ssl import paho.mqtt.client as mqtt import logging def create_logger(): logger = logging.getLogger('mqtt debug') logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) logger.addHandler(ch) return logger host = 'mqtt.ably.io' port = 8883 channel = '[product:flight-data/flight-data]flight' def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) client.subscribe(channel) def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.payload)) api_key = os.environ.get('ABLY_API_KEY', '') username, passwd = api_key.split(':') print(username) mqttc = mqtt.Client(client_id="Test", clean_session=True, userdata=None) mqttc.enable_logger(logger=create_logger()) mqttc.on_connect = on_connect mqttc.on_message = on_message mqttc.username_pw_set(username, passwd) # 启用TLS配置,适配8883端口的MQTTS加密要求 mqttc.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS_CLIENT) mqttc.connect(host, port=port, keepalive=15) mqttc.loop_forever()
异常处理补充
如果运行时出现证书校验失败的报错,可以手动指定系统CA证书路径传入tls_set()的ca_certs参数:
- Debian/Ubuntu系列系统CA证书默认路径:
/etc/ssl/certs/ca-certificates.crt - CentOS/RHEL系列系统CA证书默认路径:
/etc/pki/tls/certs/ca-bundle.crt - Windows环境可以安装certifi库,传入
certifi.where()作为CA证书路径即可
内容的提问来源于stack exchange,提问作者Jonathan Shapiro
相关产品推荐
相关产品推荐

