先说解决方案,在emqx配置文件中加一行配置然后重启emqx: listeners.ws.default.websocket.fail_if_no_subprotocol = false

 

现象:微信小程序开发在开发者工具里可以正常连接MQTT,但是真机调试时连接mqtt会报fail(不是https、wss这种弱智原因):

微信小程序真机调试连接mqtt失败原因及修复(EMQX客户端)_重启

 

 

通过观察nginx日志发现,nginx返回400错误:

微信小程序真机调试连接mqtt失败原因及修复(EMQX客户端)_配置文件_02

 

 

通过百度关键词: "GET /mqtt HTTP/1.1" 400

里面说:

模拟器调试的时候存在sec-websocket-protocol:mqtt,而真机上不存在

然后搜 sec-websocket-protocol

在nginx配置文件中尝试添加 Sec-WebSocket-Protocol

于是想到修改emqx,找到官方文档:https://www.emqx.io/docs/zh/v5.0

在官方文档搜索“小程序”,果然找到一个关键:

ws_opts.fail_if_no_subprotocol

类型boolean

默认值true

如果true,当客户端未携带Sec WebSocket Protocol字段时,服务器将返回一个错误。
注意:微信小程序需要禁用此验证。

OK,那么就是改配置了,官方文档目录中正好上一节就是“配置文件简介”,找到配置文件,加上 ws_opts.fail_if_no_subprotocol = false

然后在配置文件夹使用 find . -name "*.conf" | xargs grep "fail_if_no_subprotocol" 搜索,找到一个配置文件 emqx-example.conf

观察发现真实配置应该是

listeners.ws.$name.websocket.fail_if_no_subprotocol = false

对比 emqx.conf

listeners.ws.default.websocket.fail_if_no_subprotocol = false

关于配置文件语法,虽然文件里是类json格式,但是也可以写成小数点分割形式,具体可以看官方介绍:https://www.emqx.io/docs/zh/v5.0/configuration/configuration.html

最后,上一个真机调试成功的截图,没有 Sec-WebSocket-Protocol

微信小程序真机调试连接mqtt失败原因及修复(EMQX客户端)_nginx_03