You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS应用无法连接Docker部署的Mosquitto MQTT WebSocket

问题:ReactJS通过WebSocket连接Docker中的Mosquitto失败,日志反复显示连接关闭

我在Docker容器中运行2.0.15版本的Eclipse Mosquitto MQTT Broker,设备通过MQTT协议能正常连接,但ReactJS应用使用WebSocket连接时失败,容器日志反复出现Client react-client closed its connection。

相关配置与代码

mosquitto.conf配置

per_listener_settings true
persistence true
persistence_location /mosquitto/data/
#log_dest file /mosquitto/log/mosquitto.log

## Authentication ##
allow_anonymous false
listener 8885
password_file /mosquitto/config/password.txt

# websockets connections from react
listener 9001
protocol websockets
socket_domain ipv4

ReactJS应用代码

import React, { useState, Fragment } from 'react';
import mqtt from "precompiled-mqtt";

var options = {
    protocol: 'ws',
    username: 'smart_home_mqtt_user',
    password: 'testtest',
    clientId: 'react-client',
};
var client = mqtt.connect('ws://192.168.0.160:9001',options);

client.on('connect', () => {
    console.log("CONNECTED to broker");
});
//  MQTT topic
client.subscribe('test');

function MqttDash() {
    var note;
    client.on('message', function (topic, message) {
        note = message.toString();
        // Updates React state with message 
        setMsg(note);
        console.log(note);
        client.end();
    });

    // Sets default React state 
    const [msg, setMsg] = useState(<Fragment><em>...</em></Fragment>);

    return (
        <div >   
                <h1>Hello MQTT in React</h1>
                <p>The message payload is: {msg}</p>     
        </div>
    );
}

export default MqttDash;

Mosquitto容器日志输出

1664520991: mosquitto version 2.0.15 starting
1664520991: Config loaded from /mosquitto/config/mosquitto.conf.
1664520991: Opening ipv4 listen socket on port 8885.
1664520991: Opening ipv6 listen socket on port 8885.
1664520991: Opening websockets listen socket on port 9001.
1664520991: mosquitto version 2.0.15 running
1664521055: Client react-client closed its connection.
1664521056: Client react-client closed its connection.
1664521057: Client react-client closed its connection.
1664521058: Client react-client closed its connection.
1664521059: Client react-client closed its connection.
1664521060: Client react-client closed its connection.

解决方案

1. 修复Mosquitto WebSocket监听器的认证配置

由于开启了per_listener_settings true,全局的allow_anonymous false不会自动应用到WebSocket监听器,需要单独配置认证规则:
修改mosquitto.conf中WebSocket监听部分,添加密码文件配置:

listener 9001
protocol websockets
socket_domain ipv4
password_file /mosquitto/config/password.txt  # 与MQTT端口共用同一个密码文件

2. 修正React代码中的逻辑问题

  • 避免在组件外部初始化MQTT客户端,防止组件重复渲染时创建多个客户端实例
  • 移除client.end()调用,避免收到一条消息就断开连接
  • 使用useEffect管理客户端生命周期,确保组件卸载时正确断开连接
  • 生成随机ClientID,避免重复连接冲突

修改后的React代码:

import React, { useState, useEffect, Fragment } from 'react';
import mqtt from "precompiled-mqtt";

function MqttDash() {
    const [msg, setMsg] = useState(<Fragment><em>...</em></Fragment>);
    let client = null;

    useEffect(() => {
        const options = {
            username: 'smart_home_mqtt_user',
            password: 'testtest',
            clientId: `react-client-${Math.random().toString(16).substr(2, 8)}`, // 随机生成ClientID
        };
        client = mqtt.connect('ws://192.168.0.160:9001', options);

        client.on('connect', () => {
            console.log("CONNECTED to broker");
            client.subscribe('test'); // 连接成功后再订阅主题
        });

        client.on('message', (topic, message) => {
            const note = message.toString();
            setMsg(note);
            console.log(note);
        });

        client.on('error', (err) => {
            console.error('MQTT连接错误:', err);
        });

        client.on('close', () => {
            console.log('MQTT连接关闭');
        });

        // 组件卸载时断开连接
        return () => {
            if (client) {
                client.end();
            }
        };
    }, []);

    return (
        <div>
            <h1>Hello MQTT in React</h1>
            <p>The message payload is: {msg}</p>
        </div>
    );
}

export default MqttDash;

3. 验证Docker端口映射

确保启动容器时已经映射9001端口到主机:

docker run -d -p 8885:8885 -p 9001:9001 -v ./mosquitto/config:/mosquitto/config -v ./mosquitto/data:/mosquitto/data eclipse-mosquitto:2.0.15

4. 开启详细日志排查

修改mosquitto.conf开启全量日志,查看具体失败原因:

log_dest file /mosquitto/log/mosquitto.log
log_type all

内容的提问来源于stack exchange,提问作者pastor_j

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 19:35:26