Vue3 如何搭建mqtt及使用以及多个订阅获取数据

MQTT是一个物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。MQTT是专门针对物联网开发的轻量级传输协议。MQTT协议针对低带宽网络,低计算能力的设备,做了特殊的优化,使得其能适应各种物联网应用场景。目前MQTT拥有各种平台和设备上的客户端,已经形成了初步的生态系统。

使用前先下载相应的依赖包

npm install mqtt -S

一、长链接单个订阅方式

1、在utils里面创建mqtt.ts

// npm install mqtt -S
import * as mqtt from 'mqtt/dist/mqtt.min';
import type { MqttClient, OnMessageCallback } from 'mqtt';
import { ref, onUnmounted } from 'vue';
// 连接字符串, 通过协议指定使用的连接方式
// ws 未加密 WebSocket 连接
// wss 加密 WebSocket 连接
// mqtt 未加密 TCP 连接
// mqtts 加密 TCP 连接
// wxs 微信小程序连接
// alis 支付宝小程序连接
class MQTT {
    url: string; // mqtt地址
    //长链接单个订阅
    topic: string; //订阅地址
    client!: MqttClient;
    constructor(topic: string) {
        this.topic = topic;
        // 虽然是mqtt但是在客户端这里必须采用websock的链接方式
        this.url = 'ws://xxx.xxx.xxx.x:xxxx/mqtt';
    }

    //初始化mqtt
    init() {
        const options = {
            clean: true,// 保留会话
            // 认证信息
            clientId: 123456,
            username: "admin", //用户名 不用的话什么也不用填
            password: "admin", //密码 不用的话什么也不用填
            connectTimeout: 4000, // 超时时间
            reconnectPeriod: 4000, // 重连时间间隔
        };
        this.client = mqtt.connect(this.url, options);
        this.client.on('error', (error: any) => {
            console.log(error);
        });
        this.client.on('reconnect', (error: Error) => {
            console.log(error);
        });
    }
    //取消订阅
    unsubscribes() {
        this.client.unsubscribe(this.topic, (error: Error) => {
            if (!error) {
                console.log(this.topic, '取消订阅成功');
            } else {
                console.log(this.topic, '取消订阅失败');
            }
        });
    }
    //连接
    link() {
        this.client.on('connect', () => {
            this.client.subscribe(this.topic, (error: any) => {
                if (!error) {
                    console.log('订阅成功');
                } else {
                    console.log('订阅失败');
                }
            });
        });
    }
    //收到的消息
    get(callback: OnMessageCallback) {
        this.client.on('message', callback);
    }
    //结束链接
    over() {
        this.client.end();
    }
}

export default function useMqtt() {
    const PublicMqtt = ref<MQTT | null>(null);

    const startMqtt = (val: string, callback: OnMessageCallback) => {
        //设置订阅地址
        PublicMqtt.value = new MQTT(val);
        console.log(PublicMqtt.value)
        //初始化mqtt
        PublicMqtt.value.init();
        //链接mqtt
        PublicMqtt.value.link();
        getMessage(callback);
    };
    const getMessage = (callback: OnMessageCallback) => {
        // PublicMqtt.value?.client.on('message', callback);
        PublicMqtt.value?.get(callback);
    };
    onUnmounted(() => {
        //页面销毁结束订阅
        if (PublicMqtt.value) {
            PublicMqtt.value.unsubscribes();
            PublicMqtt.value.over();
        }
    });

    return {
        startMqtt,
    };
}
// 使用
// import useMqtt from '@/composables/utils/useMqtt';
// const { startMqtt } = useMqtt();
// startMqtt('主题topic', (topic, message) => {
//    const msg = JSON.parse(message.toString());
//    console.log(msg);
// });

2、在使用的组件进行调用 传入访问文件地址即可建立连接获取数据

import useMqtt from "@/utils/mqtt";
const { startMqtt } = useMqtt();
startMqtt("/tfc/+/zs", (topic: any, message: any) => {
  const msg = JSON.parse(message.toString());
  console.log(msg);
});

二、长链接多个订阅获取数据

// npm install mqtt -S
import * as mqtt from 'mqtt/dist/mqtt.min';
import type { MqttClient, OnMessageCallback } from 'mqtt';
import { ref, onUnmounted } from 'vue';
// 连接字符串, 通过协议指定使用的连接方式
// ws 未加密 WebSocket 连接
// wss 加密 WebSocket 连接
// mqtt 未加密 TCP 连接
// mqtts 加密 TCP 连接
// wxs 微信小程序连接
// alis 支付宝小程序连接
class MQTT {
    url: string; // mqtt地址
    topic: string[]; //订阅地址
    client!: MqttClient;
    constructor(topic: string[]) {
        this.topic = topic;
        // 虽然是mqtt但是在客户端这里必须采用websock的链接方式
        this.url = 'ws://xxx.xxx.xxx.x:xxxxx/mqtt';
    }

    //初始化mqtt
    init() {
        const options = {
            clean: true,// 保留会话
            // 认证信息
            clientId: 123456,
            username: "admin", //用户名 不用的话什么也不用填
            password: "admin", //密码 不用的话什么也不用填
            connectTimeout: 4000, // 超时时间
            reconnectPeriod: 4000, // 重连时间间隔
        };
        this.client = mqtt.connect(this.url, options);
        this.client.on('error', (error: any) => {
            console.log(error);
        });
        this.client.on('reconnect', (error: Error) => {
            console.log(error);
        });
    }
    //取消订阅
    unsubscribes(topic: string[]) {
        topic.forEach((item) => {
            this.client.unsubscribe("/sys/device/data/" + item, (error: Error) => {
                if (!error) {
                    console.log(this.topic, '取消订阅成功');
                } else {
                    console.log(this.topic, '取消订阅失败');
                }
            });
        })
    }
    //连接
    link(topic: string[]) {
        topic.forEach((item) => {
            this.client.on('connect', () => {
                this.client.subscribe("/sys/device/data/" + item, (error: any) => {
                    if (!error) {
                        console.log('订阅成功');
                    } else {
                        console.log('订阅失败');
                    }
                });
            });
        })
    }
    //收到的消息
    get(callback: OnMessageCallback) {
        this.client.on('message', callback);
    }
    //结束链接
    over() {
        this.client.end();
    }
}

export default function useMqtt() {
    let topicData: string[];
    const PublicMqtt = ref<MQTT | null>(null);
    const startMqtt = (val: string[], callback: OnMessageCallback) => {
        topicData = val;
        //设置订阅地址
        PublicMqtt.value = new MQTT(val);
        //初始化mqtt
        PublicMqtt.value.init();
        PublicMqtt.value?.link(val);
        getMessage(callback);
    };
    const getMessage = (callback: OnMessageCallback) => {
        // PublicMqtt.value?.client.on('message', callback);
        PublicMqtt.value?.get(callback);
    };
    onUnmounted(() => {
        //页面销毁结束订阅
        if (PublicMqtt.value) {
            PublicMqtt.value.unsubscribes(topicData);
            PublicMqtt.value.over();
        }
    });

    return {
        startMqtt,
    };
}

在使用的组件进行调用 传入访问文件地址即可建立连接获取数据

<script lang="ts" setup>
// 自我封装
import useMqtt from "@/utils/mqtt";
const { startMqtt } = useMqtt();

let arr = [];
startMqtt(
  ["地址1", "地址2", "地址3"],
  (topic: any, message: any) => {
    const msg = JSON.parse(message.toString());
    arr.unshift(msg);
    console.log(unique(arr))
  }
);
//这里我每秒都会接收到数据 进行数据去重
function unique(arr) {
  const res = new Map();
  return arr.filter((a) => !res.has(a.UUID) && res.set(a.UUID, 1));
}
</script>
  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以将MQTT封装成一个Vue插件,并将其注册到Vue实例中,这样就能够在多个组件中使用它了。 首先,我们要安装MQTTnpm包: ``` npm install mqtt --save ``` 然后,我们创建一个mqtt.js文件,将MQTT封装成一个插件: ```js import mqtt from 'mqtt' const mqttPlugin = { install (Vue, options) { Vue.prototype.$mqtt = mqtt.connect(options.host, options.options) } } export default mqttPlugin ``` 在这里,我们使用Vue的插件机制,在Vue实例中注册了一个全局的$mqtt属性,可以在任意组件中使用。 我们还需要在main.js文件中引入mqtt插件: ```js import Vue from 'vue' import App from './App.vue' import mqttPlugin from './mqtt.js' Vue.use(mqttPlugin, { host: 'mqtt://localhost:1883', options: { clientId: 'myClientId' } }) new Vue({ render: h => h(App) }).$mount('#app') ``` 在这里,我们使用Vue.use()方法来安装mqtt插件,并传递了host和options参数,以便连接到MQTT服务器。 现在,我们就可以在任意组件中使用$mqtt属性来连接和订阅MQTT主题了: ```js export default { mounted () { this.$mqtt.on('connect', () => { console.log('MQTT connected') this.$mqtt.subscribe('my/topic') }) this.$mqtt.on('message', (topic, payload) => { console.log(`Received message on topic ${topic}: ${payload.toString()}`) }) }, beforeDestroy () { this.$mqtt.end() } } ``` 在这个例子中,我们在组件的mounted()钩子中连接到MQTT服务器,并订阅了一个主题。在message事件中,我们打印出了收到的消息。 最后,在组件的beforeDestroy()钩子中,我们关闭了MQTT连接。 这样,我们就成功地封装了MQTT,并能够在多个组件中使用了。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值