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

先说解决方案,在emqx配置文件中加一行配置然后重启emqx: listeners.ws.default.websocket.fail_if_no_subprotocol = false (虽然配置文件看起来像json,但你放心,就这么加就行)。(配置文件路径参考:https://www.emqx.io/docs/zh/v5.0/configuration/configuration.html)

 

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

 

 

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

 

 

通过百度关键词: "GET /mqtt HTTP/1.1" 400 ,找到一篇文章:

https://blog.csdn.net/c519299013/article/details/127624143。里面说:

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

然后搜 sec-websocket-protocol 到底为何物,简单来说就是规定了ws握手期间可使用的子协议,属于可选配置。(见:https://zhuanlan.zhihu.com/p/407711596?utm_id=0)

在nginx配置文件中尝试添加 Sec-WebSocket-Protocol 头,启动nginx报错。

于是想到修改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 ,重启emqx,无效!!

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

观察发现真实配置应该是

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

对比 emqx.conf ,发现name可以写为default,于是最终修改为:

listeners.ws.default.websocket.fail_if_no_subprotocol = false

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

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

 

posted @ 2023-03-02 22:02  yanglei.xyz  阅读(1052)  评论(1编辑  收藏  举报