250 lines
7.0 KiB
JavaScript
250 lines
7.0 KiB
JavaScript
import * as commonUtils from "@/utils/common.js"
|
||
// #ifdef H5
|
||
import mqtt from "mqtt/dist/mqtt"
|
||
// #endif
|
||
// #ifdef APP-PLUS
|
||
import {
|
||
connect,
|
||
isConnected,
|
||
subscribe,
|
||
unSubscribe,
|
||
getConfig,
|
||
onConnectLost,
|
||
onReconnect,
|
||
disConnect,
|
||
publishMessage
|
||
} from "@/uni_modules/zy-mqtt";
|
||
// #endif
|
||
|
||
|
||
//封装一个类(可直接cv)
|
||
class MqttUtil {
|
||
//创建公共变量
|
||
static url;
|
||
static options;
|
||
static client;
|
||
static connected = false;
|
||
static reconnectCount = 0;
|
||
|
||
//接收创建来的数据
|
||
constructor(eventHandler) {
|
||
this.eventHandler = eventHandler;
|
||
const url = import.meta.env.VITE_BASE_MQTT;
|
||
|
||
// #ifdef H5
|
||
this.url = `mqtt://${url}`;
|
||
// #endif
|
||
// #ifdef APP-PLUS
|
||
this.url = `ws://${url}`;
|
||
// #endif
|
||
}
|
||
//初始化参数
|
||
init(userId) {
|
||
let clientId = `mqtt_app_${userId}_${this.getUUID()}`;
|
||
let username = "app_client";
|
||
let password = "app_client@2023";
|
||
let keepalive = 10; //保持连接的心跳间隔,单位为秒。
|
||
let connectTimeout = 30; //接超时的时间,单位为秒。
|
||
// #ifdef H5
|
||
this.options = {
|
||
clientId: clientId, // string 客户端的唯一标识符。
|
||
username: username, // string 连接时的用户名。
|
||
password: password, // string 连接时的密码。
|
||
keepalive: keepalive, // number 60 保持连接的心跳间隔,单位为秒。
|
||
clean: false, // boolean true 是否清除会话信息。false 时,断线重连后可继续接收未到达的消息。
|
||
reconnectPeriod: 1000, // number 1000 断开后重连的时间间隔,单位为毫秒。当设置为 0 以后将取消自动重连
|
||
connectTimeout: connectTimeout * 1000, // number 30 * 1000 连接超时的时间,单位为毫秒。
|
||
// will: { // object 无 客户端的遗嘱消息。当客户端异常断开时,broker 将会发送该消息。
|
||
// topic: '', // 发布消息的主题
|
||
// payload: '', // 要发布的消息
|
||
// qos: 0, // 消息等级
|
||
// retain: false // 保留消息标识
|
||
// },
|
||
// protocolId: "MQTT", // string MQTT 协议名称。
|
||
// protocolVersion: 4, // number MQTT 协议版本,4 表示 MQTT v3.1.1。
|
||
resubscribe: true, // boolean true 断线重连后是否自动重新订阅之前的主题。
|
||
}
|
||
// #endif
|
||
|
||
// #ifdef APP-PLUS
|
||
this.options = {
|
||
host: this.url, // 主机ip
|
||
clientId: clientId, // 客户端id
|
||
userName: username, // 用户名
|
||
password: password, // 密码
|
||
heartBeat: keepalive, // 可选,默认60秒, 心跳
|
||
cleanSession: false, // 可选,默认false,是否开启持续会话
|
||
automaticReconnect: true, // 可选,默认true,是否自动重连
|
||
timeOut: connectTimeout, // 可选,默认30秒,连接超时时间
|
||
keepAlive: false, // 可选,是否保活(息屏保活), 对于Android O及以上版本,如果你的应用处于后台,你需要将服务转变为前台服务来避免系统在一定时间后杀死服务。这需要通过创建一个持续在通知栏显示的通知来实现。
|
||
// notificationContentText, // 可选,通知内容,默认(应用正在后台运行,这有助于提供定制的服务和改善用户体验。)
|
||
// notificationContentTitle, // 可选,通知标题,默认(后台应用持续运行)
|
||
};
|
||
// #endif
|
||
}
|
||
//监听消息回调
|
||
onEventHandler(topic, data) {
|
||
console.error("topic:", topic);
|
||
console.error("data:", data);
|
||
this.eventHandler(topic, data);
|
||
}
|
||
getUUID() {
|
||
function S4() {
|
||
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
||
}
|
||
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
|
||
}
|
||
|
||
// #ifdef H5
|
||
//mqtt链接
|
||
link(userId) {
|
||
if (!this.options) {
|
||
this.init(userId);
|
||
}
|
||
this.client = mqtt.connect(this.url, this.options);
|
||
|
||
this.client.on("connect", error => {
|
||
this.connected = this.client.connected && !this.client.reconnecting;
|
||
this.reconnectCount = 0;
|
||
console.log("connect:", this.client)
|
||
console.log("connect:", this.connected)
|
||
})
|
||
this.client.on("reconnect", error => {
|
||
this.connected = this.client.connected && !this.client.reconnecting;
|
||
this.reconnectCount++;
|
||
console.log("reconnect:", this.client)
|
||
console.log(`reconnect_${this.reconnectCount}:`, this.connected)
|
||
})
|
||
this.client.on("error", error => {
|
||
console.log("error", error)
|
||
})
|
||
this.client.on("message", (topic, message) => {
|
||
console.log("接受消息")
|
||
console.log("message:", message.toString())
|
||
this.onEventHandler(topic, message);
|
||
})
|
||
this.client.on("close", () => {
|
||
console.log("已断开连接1")
|
||
this.client = null;
|
||
this.connected = false;
|
||
this.reconnectCount = 0;
|
||
});
|
||
}
|
||
//结束链接
|
||
over() {
|
||
this.client.end(false, null, () => {});
|
||
}
|
||
//订阅主题
|
||
subscribes(topics) {
|
||
if (!this.client || !this.connected) {
|
||
return;
|
||
}
|
||
console.log("subscribes", topics)
|
||
this.client.subscribe(topics, error => {
|
||
if (error) {
|
||
console.log(`订阅主题失败:`, error)
|
||
} else {
|
||
console.log(`订阅主题成功`)
|
||
}
|
||
})
|
||
}
|
||
//取消订阅
|
||
unsubscribes(topics) {
|
||
if (!this.client || !this.connected) {
|
||
return;
|
||
}
|
||
console.log("unsubscribes", topics)
|
||
this.client.unsubscribe(topics, error => {
|
||
if (!error) {
|
||
console.log("取消订阅成功")
|
||
} else {
|
||
console.log("取消订阅错误", topic)
|
||
}
|
||
})
|
||
}
|
||
//发送消息
|
||
send(message) {
|
||
// this.client.publish("test", JSON.stringify(message), res => {
|
||
// console.log(res)
|
||
// })
|
||
}
|
||
// #endif
|
||
|
||
// #ifdef APP-PLUS
|
||
//mqtt链接
|
||
link(userId) {
|
||
if (!this.options) {
|
||
this.init(userId);
|
||
}
|
||
// 先连接mqtt
|
||
connect(this.options, (res) => {
|
||
console.log("connect:", res);
|
||
// if (res.code == 200) {}
|
||
this.connected = isConnected();
|
||
this.reconnectCount = 0;
|
||
console.log("connect:", this.connected)
|
||
})
|
||
// 监听连接丢失函数
|
||
onConnectLost((res) => {
|
||
console.log("onConnectLost:", res);
|
||
this.connected = isConnected();
|
||
console.log("onConnectLost:", this.connected)
|
||
})
|
||
// 监听自动重新连接函数
|
||
onReconnect((res) => {
|
||
console.log("onReconnect:", res);
|
||
this.connected = isConnected();
|
||
this.reconnectCount++;
|
||
console.log("onConnectLost_${this.reconnectCount}:", this.connected)
|
||
})
|
||
}
|
||
//结束链接
|
||
over() {
|
||
if (!isConnected()) {
|
||
return;
|
||
}
|
||
disConnect((res) => {
|
||
console.log("接受消息:", res)
|
||
if (res.code == 200) {
|
||
this.reconnectCount = 0;
|
||
this.connected = isConnected();
|
||
}
|
||
})
|
||
}
|
||
//订阅主题
|
||
subscribes(topics) {
|
||
if (!isConnected()) {
|
||
return;
|
||
}
|
||
console.log("subscribes", topics)
|
||
if (topics && topics.length) {
|
||
topics.forEach(x => {
|
||
subscribe(x, 0, (res) => {
|
||
console.log("接受消息")
|
||
var message = JSON.stringify(res);
|
||
console.log("message:", message.toString());
|
||
})
|
||
});
|
||
}
|
||
}
|
||
//取消订阅
|
||
unsubscribes(topics) {
|
||
if (!isConnected()) {
|
||
return;
|
||
}
|
||
console.log("unsubscribes", topics)
|
||
if (topics && topics.length) {
|
||
topics.forEach(x => {
|
||
unSubscribe(x, (res) => {})
|
||
});
|
||
}
|
||
}
|
||
//发送消息
|
||
send(message) {
|
||
// publishMessage('your/topic', 2, message, (res) => {
|
||
// })
|
||
}
|
||
// #endif
|
||
}
|
||
|
||
export default MqttUtil |