使用paho.mqtt.client通过WebSocket连接MQTT服务握手失败求助
问题分析与解决方案
问题背景
尝试用paho.mqtt.client通过WebSocket连接第三方MQTT服务,代码运行时抛出WebSocket handshake error, connection not upgraded异常,但用.NET的MQTTnet库以相同参数可成功连接。
原代码
import paho.mqtt.client as mqtt def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) client.subscribe("$SYS/#") def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.payload)) client = mqtt.Client(client_id="<MY_CLIENT_ID>", transport="websockets") client.username_pw_set(username="<MY_USERNAME>",password="<MY_PASSWORD>") client.on_connect = on_connect client.on_message = on_message client.tls_set() client.connect("SERVER_ADDRESS", SERVER_PORT, 55) client.loop_forever()
异常信息
Traceback (most recent call last): File "C:\Development\CockpitHomePyScript\test.py", line 24, in <module> client.connect("SERVER_ADDRESS", 5222, 55) File "C:\Users\Ophir\AppData\Local\Programs\Python\Python310\lib\site-packages\paho\mqtt\client.py", line 914, in connect return self.reconnect() File "C:\Users\Ophir\AppData\Local\Programs\Python\Python310\lib\site-packages\paho\mqtt\client.py", line 1080, in reconnect sock = WebsocketWrapper(sock, self._host, self._port, self._ssl, File "C:\Users\Ophir\AppData\Local\Programs\Python\Python310\lib\site-packages\paho\mqtt\client.py", line 3713, in __init__ self._do_handshake(extra_headers) File "C:\Users\Ophir\AppData\Local\Programs\Python\Python310\lib\site-packages\paho\mqtt\client.py", line 3766, in _do_handshake raise WebsocketConnectionError( paho.mqtt.client.WebsocketConnectionError: WebSocket handshake error, connection not upgraded
可能的问题与解决方法
1. 缺少WebSocket路径配置
大多数MQTT over WebSocket服务要求握手时指定特定路径(比如/mqtt、/ws),paho默认不会自动添加该路径,而MQTTnet可能在内部处理了这个配置。
解决:添加WebSocket路径配置
# 在connect之前添加 client.ws_set_options(path="/mqtt") # 替换为服务实际要求的路径
2. TLS配置与端口不匹配
- 如果服务使用的是普通WebSocket(ws协议),不要调用
tls_set(),否则会尝试加密连接导致握手失败; - 如果服务使用的是加密WebSocket(wss协议),要确认端口是服务的wss端口(比如443),而非ws端口(比如5222)。若服务证书存在验证问题(仅测试环境使用),可以跳过证书验证:
client.tls_set() client.tls_insecure_set(True) # 跳过证书验证,生产环境禁用
3. 缺少必要的握手请求头
部分服务会验证WebSocket握手的Origin等请求头,paho需要手动添加这些头:
client.ws_set_options(headers={"Origin": "https://your-allowed-origin.com"})
修改后的示例代码
import paho.mqtt.client as mqtt def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) client.subscribe("$SYS/#") def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.payload)) client = mqtt.Client(client_id="<MY_CLIENT_ID>", transport="websockets") client.username_pw_set(username="<MY_USERNAME>", password="<MY_PASSWORD>") # 根据服务实际情况调整以下配置 client.ws_set_options(path="/mqtt") # 添加WebSocket路径 # 如果是wss协议,启用TLS并按需配置证书验证 # client.tls_set() # client.tls_insecure_set(True) client.on_connect = on_connect client.on_message = on_message client.connect("SERVER_ADDRESS", SERVER_PORT, 55) client.loop_forever()
内容的提问来源于stack exchange,提问作者developer82
相关产品推荐
相关产品推荐

