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

用TypeScript连接Azure VM中Mosquitto MQTT服务器的故障排查求助

解决Azure VM上Mosquitto与React前端的MQTT/WebSocket连接问题

问题背景

我开发了一个React+TypeScript组件用于订阅MQTT主题并展示消息,但遇到两个核心问题:

  1. 前端控制台报错:WebSocket连接到wss://20.198.14.124/mqtt失败
  2. 修改Mosquitto配置后启动服务,出现Error: Cannot assign requested address错误

React组件代码

import React, { useEffect } from "react";
import mqtt, { MqttClient } from "mqtt";
import { v4 as uuidv4 } from "uuid";

const Subscribe = () => {
  useEffect(() => {
    const topic: string = "jobstatus";
    const mqttBrokerUrl = 'wss://myipaddress:8080/mqtt'; 
    const options = {
        clientId: 'Testing',
        username: 'admin', 
        password: 'admin',
    };
    const client: MqttClient = mqtt.connect(mqttBrokerUrl, options);
    
    function handleMessage(topic: string, message: Buffer) {
      const messageString: string = message.toString();
      console.log(`Received message on topic "${topic}": ${messageString}`);
      updateUI(messageString);
    }

    client.on("connect", () => {
      console.log("Connected to MQTT broker");
      client.subscribe(topic, (err) => {
        if (err) {
          console.error(`Error subscribing to topic "${topic}": ${err}`);
        } else {
          console.log(`Subscribed to topic "${topic}"`);
        }
      });
    });

    client.on("message", handleMessage);

    function updateUI(message: string) {
      console.log("Updating UI with message:", message);
    }

    return () => {
      client.unsubscribe(topic, (err) => {
        if (err) {
          console.error(`Error unsubscribing from topic "${topic}": ${err}`);
        } else {
          console.log(`Unsubscribed from topic "${topic}"`);
        }
        client.end();
      });
    };
  }, []); 
  return (
    <div>
      <div>MQTT Messages...</div>
    </div>
  );
}; 

原Mosquitto配置及启动错误

配置文件内容

listener 1883
listener 8080
protocol websockets
allow_anonymous true

启动错误日志

1702358221: mosquitto version 1.6.9 starting
1702358221: Config loaded from /etc/mosquitto/mosquitto.conf.
1702358221: Opening ipv4 listen socket on port 1883.
1702358221: Error: Cannot assign requested address
1702358231: mosquitto version 1.6.9 starting
1702358231: Config loaded from /etc/mosquitto/mosquitto.conf.
1702358231: Opening ipv4 listen socket on port 8080.
1702358231: Error: Cannot assign requested address.

解决方案步骤

1. 修正Mosquitto监听配置

修改/etc/mosquitto/mosquitto.conf,为listener指定绑定地址为0.0.0.0(监听所有网络接口):

listener 1883 0.0.0.0
listener 8080 0.0.0.0
protocol websockets
allow_anonymous true

说明:Azure VM的网络接口有公网IP和私有IP,绑定0.0.0.0可避免指定特定IP导致的绑定失败问题

2. 配置Azure VM网络安全组(NSG)

  • 添加入站规则,允许**端口1883(MQTT)和端口8080(MQTT over WebSocket)**的TCP流量
  • 测试阶段可将源IP范围设为0.0.0.0/0,正式环境限制为前端应用的IP范围

3. 更新React组件的连接配置

  • 替换mqttBrokerUrl为Azure VM的公网IP:
    const mqttBrokerUrl = 'wss://20.193.14.124:8080/mqtt';
    
  • 用UUID生成唯一clientId,避免重复连接冲突:
    clientId: `Testing_${uuidv4()}`,
    

4. 完善前端UI展示逻辑

添加状态管理存储消息并渲染:

import React, { useEffect, useState } from "react";
import mqtt, { MqttClient } from "mqtt";
import { v4 as uuidv4 } from "uuid";

const Subscribe = () => {
  const [messages, setMessages] = useState<string[]>([]);

  useEffect(() => {
    const topic: string = "jobstatus";
    const mqttBrokerUrl = 'wss://20.193.14.124:8080/mqtt'; 
    const options = {
        clientId: `Testing_${uuidv4()}`,
        username: 'admin', 
        password: 'admin',
    };
    const client: MqttClient = mqtt.connect(mqttBrokerUrl, options);
    
    function handleMessage(topic: string, message: Buffer) {
      const messageString: string = message.toString();
      console.log(`Received message on topic "${topic}": ${messageString}`);
      updateUI(messageString);
    }

    client.on("connect", () => {
      console.log("Connected to MQTT broker");
      client.subscribe(topic, (err) => {
        if (err) {
          console.error(`Error subscribing to topic "${topic}": ${err}`);
        } else {
          console.log(`Subscribed to topic "${topic}"`);
        }
      });
    });

    client.on("message", handleMessage);

    function updateUI(message: string) {
      setMessages(prev => [...prev, message]);
    }

    return () => {
      client.unsubscribe(topic, (err) => {
        if (err) {
          console.error(`Error unsubscribing from topic "${topic}": ${err}`);
        } else {
          console.log(`Unsubscribed from topic "${topic}"`);
        }
        client.end();
      });
    };
  }, []); 

  return (
    <div>
      <h3>MQTT Messages...</h3>
      <div style={{marginTop: '1rem'}}>
        {messages.length === 0 ? (
          <p>No messages received yet</p>
        ) : (
          messages.map((msg, idx) => (
            <div key={idx} style={{padding: '0.5rem', borderBottom: '1px solid #eee'}}>
              {msg}
            </div>
          ))
        )}
      </div>
    </div>
  );
}; 

5. 重启Mosquitto服务并验证

执行以下命令重启服务:

sudo systemctl restart mosquitto

查看服务状态确认启动成功:

sudo systemctl status mosquitto

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:57:42