在Vue中使用MQTT实现通信过程

 更新时间:2025年07月30日 09:31:15   作者:s_Myint  
文章介绍了在Vue项目中集成MQTT的步骤:安装mqtt.js库,创建MQTT连接工具类以实现复用,通过Vue组件或直接在页面使用MQTT客户端,最后强调这是个人经验分享,鼓励支持脚本之家

一、安装 MQTT 客户端库

我们使用 mqtt.js,它是一个支持浏览器环境的 MQTT 客户端库。

通过以下命令安装:

npm install mqtt

二、创建 MQTT 连接工具类

为了方便管理和复用 MQTT 客户端,我们创建一个工具类 mqttClient.js,放在 src/utils 目录下:

import mqtt from 'mqtt';

class MQTTClient {
  constructor(options) {
    this.client = null;
    this.messages = [];
    this.subscribers = {};
    this.defaultOptions = {
      clientId: 'vue-client_' + Math.random().toString(16).substr(2, 8),
      clean: true,
      connectTimeout: 4000,
      //username: '账号',
      //password: '密码'
    };
    this.options = { ...this.defaultOptions, ...options };
  }

  connect(brokerUrl) {
    return new Promise((resolve, reject) => {
      try {
        this.client = mqtt.connect(brokerUrl, this.options);

        this.client.on('connect', () => {
          console.log('连接成功');
          resolve(this.client);
        });

        this.client.on('error', (err) => {
          console.error('连接失败:', err);
          reject(err);
        });

        this.client.on('message', (topic, payload) => {
          const message = {
            topic: topic,
            content: payload.toString()
          };
          this.messages.push(message);
          
          // 如果有订阅者,通知所有订阅了该主题的回调
          if (this.subscribers[topic]) {
            this.subscribers[topic].forEach(callback => callback(message));
          }
        });

        this.client.on('close', () => {
          console.log('MQTT connection closed');
        });
      } catch (err) {
        reject(err);
      }
    });
  }
// 订阅主题
  subscribe(topic, callback, qos = 0) {
    if (!this.client || this.client.connected === false) {
      // console.error('MQTT not connected');
      return;
    }

    this.client.subscribe(topic, { qos }, (err) => {
      if (!err) {
        console.log(`Subscribed to ${topic}`);
        // 存储订阅回调
        if (!this.subscribers[topic]) {
          this.subscribers[topic] = [];
        }
        this.subscribers[topic].push(callback);
      }
    });
  }
// 取消订阅指定主题的方法
  unsubscribe(topic) {
    if (!this.client || this.client.connected === false) {
      console.error('MQTT not connected');
      return;
    }

    this.client.unsubscribe(topic, (err) => {
      if (!err) {
        console.log(`Unsubscribed from ${topic}`);
        // 移除订阅回调
        if (this.subscribers[topic]) {
          delete this.subscribers[topic];
        }
      }
    });
  }
// 发送消息
  publish(topic, message, qos = 0, retain = false) {
    if (!this.client || this.client.connected === false) {
      console.error('MQTT not connected');
      return;
    }

    this.client.publish(topic, message, { qos, retain }, (err) => {
      if (err) {
        console.error('Publish error:', err);
      }
    });
  }
// 取消连接
  disconnect() {
    if (this.client) {
      this.client.end();
      this.client = null;
    }
  }

  getMessages() {
    return [...this.messages];
  }

  clearMessages() {
    this.messages = [];
  }
}

export default MQTTClient;

三、在 Vue 组件中使用

我们创建一个 Vue 组件来使用 MQTT 客户端

<template>
  <div>
    <h3>接收的 MQTT 消息:</h3>
    <ul>
      <li v-for="(msg, index) in messages" :key="index">
        {{ msg.topic }}: {{ msg.content }}
      </li>
    </ul>
    <!-- <ul>
      <li v-for="(msg, index) in top2" :key="index">
        {{ msg.topic }}: {{ msg.content }}
      </li>
    </ul> -->
    <button @click="publishMessage">发送消息</button>
  </div>
</template>

<script>
import MQTTClient from '@/util/mqtt';

export default {
  data() {
    return {
      mqttClient: null,
      messages: [],
      top2:[]
    };
  },
  mounted() {
    this.initMQTT();
  },
  methods: {
    initMQTT() {
      this.mqttClient = new MQTTClient();
      
      // 连接到 MQTT 代理
       const url="ws://"+"你的地址"+":8083/mqtt"  //例如ws://172.18.14.167:8083/mqtt
      this.mqttClient.connect(url)
        .then(() => {
          console.log('订阅成功');
          // 订阅主题
          this.mqttClient.subscribe('kpmqqt-lims-data-top1', (message) => {
            this.messages.push(message);
          });
          // this.mqttClient.subscribe('kpmqqt-lims-data-top2', (message) => {
          //   this.top2.push(message);
          // });
        })
        .catch(err => {
          console.error('MQTT connection failed:', err);
        });
    },
    publishMessage() {
      if (this.mqttClient) {
        this.mqttClient.publish('kpmqqt-lims-data-top1', 'Hello from 测试Vue2!');
        // this.mqttClient.publish('kpmqqt-lims-data-top2', 'Hello from 测试!');
      } else {
        console.error('MQTT client not initialized');
      }
    }
  },
  beforeDestroy() {
    if (this.mqttClient) {
      this.mqttClient.disconnect();
    }
  }
};
</script>

四、或者直接在页面使用

<template>
  <div>
    <h3>接收的 MQTT 消息:</h3>
    <ul>
      <li v-for="(msg, index) in messages" :key="index">
        {{ msg.topic }}: {{ msg.content }}
      </li>
    </ul>
  </div>
</template>

<script>
import mqtt from 'mqtt';

export default {
  data() {
    return {
      client: null,
      messages: []
    };
  },
  mounted() {
    this.initMQTT();
  },
  methods: {
    initMQTT() {
      const options = {
        clientId: 'vue-client_' + Math.random().toString(16).substr(2, 8),
        clean: true,
        connectTimeout: 4000
      };
      const url="ws://"+"你的地址"+":8083/mqtt"  //例如ws://172.18.14.167:8083/mqtt
      this.client = mqtt.connect(url, options);

      this.client.on('connect', (e) => {
        this.subscribeTopics();
      });

      this.client.on('message', (topic, payload) => {
        this.messages.push({
          topic: topic,
          content: payload.toString()
        });
      });
    },
    subscribeTopics() {
      this.client.subscribe(['sensor/#'], { qos: 1 });
    }
  },
  beforeDestroy() {
    if (this.client) {
      this.client.end();
    }
  }
};
</script>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue2和vue3部署到服务器子目录为空白页问题及解决

    vue2和vue3部署到服务器子目录为空白页问题及解决

    这篇文章主要介绍了vue2和vue3部署到服务器子目录为空白页问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • vue.js实现简单购物车功能

    vue.js实现简单购物车功能

    这篇文章主要为大家详细介绍了vue.js实现简单购物车功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • 浅谈Vue-cli单文件组件引入less,sass,css样式的不同方法

    浅谈Vue-cli单文件组件引入less,sass,css样式的不同方法

    下面小编就为大家分享一篇浅谈Vue-cli单文件组件引入less,sass,css样式的不同方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • axios 发 post 请求,后端接收不到参数的完美解决方案

    axios 发 post 请求,后端接收不到参数的完美解决方案

    这篇文章主要介绍了axios 发 post 请求,后端接收不到参数的解决方案,场景很简单,就是一个正常 axios post 请求,本文给大家分享问题原因分析及解决方案需要的朋友可以参考下
    2022-12-12
  • Vue中自定义标签及其使用方式

    Vue中自定义标签及其使用方式

    这篇文章主要介绍了Vue中自定义标签及其使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • vue.js 实现点击按钮动态添加li的方法

    vue.js 实现点击按钮动态添加li的方法

    今天小编就为大家分享一篇vue.js 实现点击按钮动态添加li的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Vue 中自定义文件上传组件的实现代码

    Vue 中自定义文件上传组件的实现代码

    在Vue项目中,自定义文件上传组件能够提升用户交互体验和界面控制,样式可根据需求定制,在其他组件中引用时,可以进一步扩展功能,如文件类型限制和上传进度条,本文给大家介绍Vue 中自定义文件上传组件的实现代码,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • vue3+vite使用postcss-pxtorem、autoprefixer自适应和自动添加前缀

    vue3+vite使用postcss-pxtorem、autoprefixer自适应和自动添加前缀

    这篇文章主要介绍了vue3+vite使用postcss-pxtorem、autoprefixer自适应和自动添加前缀方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Vue3中关于ref和reactive的区别分析

    Vue3中关于ref和reactive的区别分析

    这篇文章主要介绍了vue3关于ref和reactive的区别分析,文中通过示例代码介绍的非常详细,具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-06-06
  • 深入浅析Vue.js 中的 v-for 列表渲染指令

    深入浅析Vue.js 中的 v-for 列表渲染指令

    当遍历一个数组或枚举一个对象进行迭代循环展示时,就会用到列表渲染指令 v-for。这篇文章主要介绍了Vue.js 中的 v-for 列表渲染指令,需要的朋友可以参考下
    2018-11-11

最新评论