jsy-app/utils/mqttUtil.js
2024-09-30 11:01:45 +08:00

250 lines
7.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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