You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:20:35