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

使用MQTT.js连接HiveMQ Broker时WebSocket连接失败

问题核心诱因
  • NextJS 服务端渲染(SSR)环境冲突:async-mqtt 库会根据运行环境自动选择连接实现,若未显式标记组件为客户端组件,MQTT连接初始化逻辑会先在Node.js服务端执行,加载Node侧TCP连接逻辑,待客户端hydrate阶段,预设的wss协议参数无法正确透传到浏览器WebSocket构造器,最终出现代码写了wss、实际发起ws明文连接的异常。
  • useEffect 逻辑死循环:将client状态加入useEffect依赖数组,每次setClient触发状态更新都会重复执行effect逻辑,导致重复注册事件监听、生成多个客户端实例抢连。
  • 连接参数冲突+配置缺失:已在URL前缀指定wss://协议的同时,又在options中重复传入protocol、port参数,触发MQTT.js地址解析逻辑异常;另外HiveMQ WebSocket服务默认需要携带/mqtt路径,缺失路径也会导致连接失败。
  • 端口使用错误:此前测试的1883、8883为原生MQTT TCP协议端口,不支持WebSocket连接,浏览器无法直接对接这两个端口。
修复步骤
  1. 替换依赖库,规避兼容性问题
    停止使用久未更新、浏览器侧兼容性差的async-mqtt,直接安装官方维护的mqtt库:
    npm install mqtt
    
  2. 修正组件代码,确保连接仅在浏览器侧初始化一次
    如果使用NextJS 13+ App Router,必须在文件顶部加'use client'标记为客户端组件,修正后的完整代码如下:
    'use client';
    import { useEffect, useState } from 'react';
    import mqtt, { MqttClient } from 'mqtt';
    
    const Page = () => {
      const [client, setClient] = useState<MqttClient | null>(null);
    
      useEffect(() => {
        // 非浏览器环境直接返回,避免SSR阶段初始化连接
        if (typeof window === 'undefined') return;
    
        // 直接写全连接地址,不要重复传protocol/port避免参数冲突,注意末尾加/mqtt路径
        const connectUrl = "wss://<你的HiveMQ Broker地址>:8884/mqtt";
        const mqttClient = mqtt.connect(connectUrl, {
          username: "你的用户名",
          password: "你的密码",
          // 生成随机clientId,避免多标签页打开时相同ID互踢
          clientId: `web_${Math.random().toString(16).slice(2)}`,
          keepalive: 60,
          clean: true,
          reconnectPeriod: 1000,
        });
    
        // 事件仅绑定一次
        mqttClient.on("connect", () => {
          console.log("MQTT连接成功");
          // 连接成功后再执行订阅操作
          mqttClient.subscribe("你需要订阅的主题", (err) => {
            if (!err) console.log("主题订阅成功");
          });
        });
    
        mqttClient.on("error", (err) => {
          console.error("连接错误: ", err);
          mqttClient.end();
        });
    
        mqttClient.on("reconnect", () => {
          console.log("尝试重连中...");
        });
    
        mqttClient.on("message", (topic, message) => {
          const payload = { topic, message: message.toString() };
          console.log("收到消息:", payload);
        });
    
        setClient(mqttClient);
    
        // 组件卸载时主动断开连接,清理内存
        return () => {
          mqttClient.end();
        };
      // 依赖数组留空,仅在组件首次挂载时执行一次连接逻辑
      }, []);
    
      return (
        <>页面业务内容</>
      );
    };
    
    export default Page;
    
  3. 核对Broker侧配置
    • 确认自部署HiveMQ的8884端口WebSocket监听器已开启TLS,且配置的访问路径为/mqtt
    • 检查防火墙、安全组规则,放通8884端口的入站访问,配置跨域规则允许你的站点域名发起WebSocket请求
    • 若使用HiveMQ Cloud公有服务,确认连接地址、端口、账号密码与控制台给出的WebSocket参数完全一致
  4. 连接验证
    打开浏览器开发者工具的网络面板,过滤WS类型请求,看到目标连接状态为101 Switching Protocols即表示连接建立成功。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:39:38