先说解决方案,在emqx配置文件中加一行配置然后重启emqx: listeners.ws.default.websocket.fail_if_no_subprotocol = false
现象:微信小程序开发在开发者工具里可以正常连接MQTT,但是真机调试时连接mqtt会报fail(不是https、wss这种弱智原因):
通过观察nginx日志发现,nginx返回400错误:
通过百度关键词: "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