vue中使用mqtt详细教程(兼容ie)
vue中使用mqtt的漫漫长路,记录的是一个探索实践的过程。
一想到你我就呕…呕呕~~~,咳咳,跑偏了。这篇文章主要记录我在vue使用mqtt的过程,以便大家少走弯路
MQTT为何物?(各位看官,马上会有一堆废话,注意走位)
百度百科:
MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,基于TCP/IP;
有三种消息发布服务质量(qos):
“至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
“至少一次”,确保消息到达,但消息重复可能会发生。
“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
我的理解:如果A与B要通信,其中需要一个消息中间件C(broker),无论A/B谁发布消息(理想情况是有更新时就发布),都发向C,无论谁订阅消息都向C订阅,然后不断获取到最新的A/B的消息。订阅的终端可有多个(类似,北斗只负责发位置信息,终端设备只需要获取就可以了,且是最新的)。
大概这样子(嘘…菜鸟教程上偷的图):
提示: 你可能需要知道你的
mqtt
链接(用户名,密码,地址等)是否可用,提供两个网站
mqtt
测试网站:(推荐第二个,第一改版了,代码能连接上,它却连接不上)
MQTT WebSocket Toolkit、
HiveMQ
正文
想在vue中使用,先安装:
cnpm install mqtt -S//这样默认给你安装的是4.1.0版本
总共主流版本有三个(我是jsdelivr看的, 【写文章时最新时4.1.0】其实@4.1.0
是默认安装,所以它的高下载量并不代表其稳定,就像现在的4.2.6一样)
建议大家安装3.0.0或2.18.8,
2021年5月19日13:32:13更新
版本
@3.0.0
、@4.2.6
,当连续(for循环)发布2个以上链接时,连接成功,当时除第一个外都会发布失败(client disconnecting),我已经降版本到2.18.8!哎~~
cnpm install mqtt@3.0.0 -S
因为ie(包括以ie为内核的360急速浏览器)上不识别4.1.0版本的es6语法。我曾尝试在babel.config.js有过如下配置想转为es5.
module.exports = {
presets: [
['@vue/app', {
'polyfills': [
'es6.promise',
'es6.symbol'
],
useBuiltIns: 'usage' //使用usage不用安装babel/polyfill和引入
}]
],
plugins: ['@babel/plugin-transform-arrow-functions']//需要安装
}
均无果,各位可以去尝试。本人限于水平,若有大佬配置成功欢迎留言交流。
我只在一个页面用到了,所以在单页面中引入
import mqtt from "mqtt"
注意: 一个项目保持一个mqtt链接即可,不同页面可以不同的主题订阅或发布不同主题。
接着贴一下使用代码(代码中注释很全)
//引入connect配置
import { mqttConfig } from "../../commonParams/index.js"
关于配置项:
- 端口,用户名,密码是后台约定(提供)
- 下面我注释掉的配置项是默认配置,什么?你不信?看这MQTT.js#connect
//commonParams/index.js
export const mqttConfig = {
port: 8083,
// keepalive: 60,
// clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
// protocolId: 'MQTT',
// protocolVersion: 4,
// clean: true,
}
定义了两个函数:
/*
注释中所提到的后台即为发布端/订阅端,
*/
// 初始化mqtt
initMqtt(topic){
const _this = this;
//建立连接,需要搭建消息中间件服务器的(我这里是后台)提供用户名或密码
const cfg = Object.assign(mqttConfig, {
username: 'xxxx1',
password: 'xxx2',
});
// 在data中定义MQTT,以便断开连接
// ws://xxxxx是连接地址,后台提供,wss是https连接
_this.MQTT = mqtt.connect('ws://xxxxx', cfg)
_this.MQTT.on('error', (e) => {
_this.MQTT.end();
});
//建立连接后订阅主题
_this.MQTT.on('connect', () => {
// 订阅一个主题
_this.MQTT.subscribe(topic, { qos: 1 }, err => {
if (!err) {
console.info(' ---- 订阅成功')
}else{
console.warn('订阅失败')
}
})
});
// 后台发送的消息
_this.MQTT.on('message', function (top, message) {
//发送过来的如果是对象你是需要解析的。
const res = JSON.parse(message.toString());
const TOP = top.replace('tops/','');
console.log(top + ': ', res);
//根据不同主题进行赋值操作
switch(TOP){
case "top1":
_this.data1 = [res];
break;
case "top2":
_this.data2 = [...res];
break;
//其他情况
}
});
// 其他异常事件
_this.MQTT.on('reconnect', () => {
console.info('正在重连')
});
_this.MQTT.on('disconnect', (error) => {
console.info('服务器断开:', error)
});
_this.MQTT.on('close', () => {
_this.MQTT.end();
});
},
上面你可能注意到,this.MQTT为全局变量,这是为了离开此页面时销毁mqtt链接
beforeDestroy(){
if(this.MQTT.end) this.MQTT.end();
},
// 发布mqtt,用户名密码和连接配置找后台要
mqttPublish(topic){
const _this = this;
const cfg = Object.assign(mqttConfig, {
username: 'xxx2',
password: 'xxxx',
});
_this.MQTT = mqtt.connect('ws://xxxx', cfg)
_this.MQTT.on('connect', (e) => {
//建立连接后就发布就行了,主题和后台约定。
//还有qos,就是开头提到的消息发布服务质量。
_this.MQTT.publish(topic,JSON.stringify(_this.publicMSG), { qos: 1 }, error => {
if (!error) {
this.MQTT.end();
}else{
console.warn('发布失败')
}
})
});
},
然后调用就好了
created(){
/*
+ 通配一层(tops/x,top/x1),
# 通配0~多层(tops/x, tops/,tops/x/x/x)
当有多个主题是,前面分个一级主题(tops)比较适合后面跟+号就所有 tops/ 开头都能订阅了
*/
this.initMqtt('tops/+');
},
需要发布时:
//注意后台订阅的时候一级主题也是tops,你们约定就行
this.mqttPublish('tops/top3')
以上。
予人玫瑰,手留余香~~~,
更多推荐
所有评论(0)