浏览器端使用JS连接MQTT Broker报错,如何解决?
浏览器端JS连接MQTT broker故障排查方案
问题描述
我尝试使用JS在浏览器中建立MQTT连接,编写的初始代码如下:
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script> <script> // 全局初始化mqtt变量 const clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8) const host = 'ws://broker.***.***.com:9883' const options = { keepalive: 60, clientId: clientId, username: '***', password: '***', protocolId: 'MQTT', protocolVersion: 4, clean: true, reconnectPeriod: 1000, connectTimeout: 30 * 1000, will: { topic: 'WillMsg', payload: 'Connection Closed abnormally..!', qos: 0, retain: false }, } console.log('Connecting mqtt client') const client = mqtt.connect(host, options) client.on('connect', () => { console.log('Client connected:' + clientId) // 订阅逻辑 }) </script>
运行后浏览器报错,查询资料后调整代码添加了证书路径配置:
<script src="../browserMqtt.js"></script> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <script> var options = { keyPath: '../credentials/client-key.pem', certPath: '../credentials/client-cert.pem', rejectUnauthorized : false, ca: ['../credentials/a-cert.pem'], protocolId: 'MQTT', username: '***', password: '***', clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8) }; var client = mqtt.connect('ws://broker.***.***.com:9883',options); client.on('connect', function(){ console.log('Connected'); }); </script>
调整后依旧报错,使用的Mosquitto Broker配置如下:
allow_anonymous false password_file /mosquitto/config/passwd #TCP listener 1883 socket_domain ipv4 #SSL listener 8883 socket_domain ipv4 cafile /mosquitto/config/tls/ca/ca-cert.pem certfile /mosquitto/config/tls/server/server-cert.pem keyfile /mosquitto/config/tls/server/server-key.pem tls_version tlsv1.2 socket_domain ipv4 #WSS listener 9883 socket_domain ipv4 protocol websockets cafile /mosquitto/config/tls/ca/ca-cert.pem certfile /mosquitto/config/tls/server/server-cert.pem keyfile /mosquitto/config/tls/server/server-key.pem tls_version tlsv1.2 persistence true persistence_location /mosquitto/data/ log_dest file /mosquitto/log/mosquitto.log log_timestamp_format %Y-%m-%dT%H:%M:%S log_type all
解决方案
- 协议前缀修正:你Mosquitto的9883端口配置的是带TLS加密的WebSocket服务(WSS),但代码里用的是明文WebSocket协议前缀
ws://,必须改成wss://才能匹配broker的配置。 - 移除无效证书配置:
keyPath、certPath、ca这些证书路径配置仅在Node.js环境下生效,浏览器处于沙箱安全限制,无法直接读取本地文件系统的证书文件,这些配置在前端代码中完全无效。如果使用自签证书,需要将根证书导入到客户端浏览器的受信任根证书列表;生产环境建议使用公共可信CA颁发的证书即可自动完成验证。 - 移除冗余库引入:不要同时引入多个MQTT客户端库,同时引入MQTT.js和Paho MQTT会存在命名冲突风险,仅保留官方MQTT.js的CDN引入即可,删除其他冗余的MQTT库引用。
- 增加错误监听:在代码中添加error事件监听,打印具体错误信息,方便快速定位问题。
- 连通性与配置校验:先确认服务器9883端口的防火墙规则已放行,可直接在浏览器中访问wss地址测试连通性,也可以查看Mosquitto的运行日志,确认连接失败的具体原因,比如用户名密码错误、证书验证失败等。
修正后可直接使用的代码示例:
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <script> const clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8) // 替换为你自己的broker域名,协议前缀用wss const host = 'wss://broker.***.***.com:9883' const options = { keepalive: 60, clientId: clientId, username: '替换为实际用户名', password: '替换为实际密码', protocolId: 'MQTT', protocolVersion: 4, clean: true, reconnectPeriod: 1000, connectTimeout: 30 * 1000, will: { topic: 'WillMsg', payload: 'Connection Closed abnormally..!', qos: 0, retain: false } } console.log('Connecting mqtt client') const client = mqtt.connect(host, options) client.on('connect', () => { console.log('Client connected:' + clientId) }) // 添加错误监听,方便排查问题 client.on('error', (err) => { console.error('Connection failed: ', err) client.end() }) </script>
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

