Eclipse-mosquitto 2.0.x WebSocket可发布但订阅无消息接收求助
背景
原本使用Eclipse-mosquitto 1.6.15,通过1883端口(内部MQTT)、8883端口(外部MQTT)及9001端口的WebSocket在Web服务器展示数据,一切正常。为启用TLS 1.3特性,计划迁移至Mosquitto 2.0.x版本。
内部WebSocket配置
原有配置:
listener 9001 protocol websockets auth_opt_jwt_alg HS256 auth_opt_jwt_sec_base64 TOKEN auth_opt_jwt_validate_exp false auth_opt_jwt_validate_sub_match_username false
尝试过的补充配置:
listener 9001 0.0.0.0 socket_domain ipv4
连接与订阅日志(显示操作正常)
1696498621: Client client_old_XXX closed its connection. <= on a refresh 1696498621: -- [wsisrv|1f|adopted] (0) 2.066min 1696498622: ++ [wsisrv|20|adopted] (1) 1696498625: Client <unknown> closed its connection. 1696498625: -- [wsisrv|20|adopted] (0) 3.078s 1696498627: New client connected from IP:PORT as client_new_XXX (p1, c1, k65535, u'configurator'). 1696498627: No will message specified. 1696498627: Sending CONNACK to client_new_XXX (0, 0) 1696498628: Received SUBSCRIBE from client_new_XXX 1696498628: /control/+/+/+ (QoS 0) 1696498628: Sending SUBACK to client_new_XXX 1696498628: Received SUBSCRIBE from client_new_XXX 1696498628: /state/+/+/+ (QoS 0) 1696498628: Sending SUBACK to client_new_XXX 1696498628: Received SUBSCRIBE from client_new_XXX 1696498628: /telemetry/+/+/+ (QoS 0) 1696498628: Sending SUBACK to client_new_XXX
注:client_new_XXX为唯一客户端ID
问题现象
WebSocket连接保持活跃,客户端可以正常发布消息,但无法接收已订阅主题的消息(通过Firefox的WSS调试控制台仅能看到客户端自身发布的消息)。
排查方向
- 怀疑Mosquitto 2.0.x版本的行为变化导致,但未找到明确证据
- 怀疑libwebsockets 4.2.1版本影响WebSocket消息转发,有资料显示降级至v3.x.x可解决,但使用官方Docker镜像无法单独降级该库
- 目前已回退至1.6.15版本,仅启用TLS 1.2,寻求迁移至2.0.x并启用TLS 1.3的解决方案
解决建议
检查并配置严格的访问控制规则
Mosquitto 2.0.x默认禁用匿名访问(allow_anonymous默认值为false),且ACL规则逻辑较1.6.x更严格。即使订阅操作返回SUBACK,也可能因权限不足无法接收消息。- 在
mosquitto.conf中指定ACL文件:acl_file /mosquitto/config/acl.conf - 在
acl.conf中为用户configurator配置订阅权限:user configurator topic read /control/+/+/+ topic read /state/+/+/+ topic read /telemetry/+/+/+ # 若需要发布权限,添加对应规则 topic write #
- 在
验证WebSocket监听器的TLS 1.3配置
若9001端口启用WSS配合TLS 1.3,需确保监听器配置完整的证书链及TLS版本:listener 9001 protocol websockets cafile /mosquitto/config/ca.crt certfile /mosquitto/config/server.crt keyfile /mosquitto/config/server.key tls_version tlsv1.3 # 保留原有JWT认证配置 auth_opt_jwt_alg HS256 auth_opt_jwt_sec_base64 TOKEN auth_opt_jwt_validate_exp false auth_opt_jwt_validate_sub_match_username false同时确认Web应用的连接URL已从
ws://切换为wss://。解决libwebsockets版本兼容问题
官方Docker镜像的libwebsockets版本与Mosquitto绑定,无法单独降级。可选择:- 使用第三方维护的、基于libwebsockets 3.x的Mosquitto 2.0.x镜像
- 自行构建Docker镜像:在Dockerfile中指定libwebsockets版本为3.2.2(兼容Mosquitto 2.0.x),编译时替换依赖库
启用Debug日志定位问题
在mosquitto.conf中添加log_type all,重启后查看详细日志,重点关注消息转发阶段的输出,确认Mosquitto是否尝试向WebSocket客户端推送消息,是否有权限或网络相关错误。简化配置排除干扰
暂时移除JWT认证配置,设置allow_anonymous true进行测试。若消息接收恢复正常,再逐步添加认证配置,排查是否为JWT规则与新版本的兼容性问题。
内容的提问来源于stack exchange,提问作者Florian Gallet

