yimultiscreenserver-sdk-web
Version:
YiMultiScreenServer SDK for Web
163 lines • 6.67 kB
JavaScript
import { SDKLog } from "../../util/SDKLog";
import { Utils } from "../../util/Utils";
import { MQTTConnectOption } from "./MQTTConnectOption";
import { MsgType } from "./message/MsgType";
import { MessageParser } from "./parser/MessageParser";
export class MQTTLogic {
constructor(clientId) {
this.TAG = "MQTTLogic";
this.messageTimestampOfSenderUnderTopics = new Map();
this.parser = new MessageParser();
this.clientId = clientId;
this.config = null;
this.displayCode = -1;
this.isConnected = false;
}
setMQTTClientImpl(impl, config) {
this.client = impl;
this.config = config;
this.client?.init(this.getConfig().getBroker(), this.clientId);
}
/**
* 连接MQTT服务器
* @param displayCode 传入值<=0时,代表需要通配(#)
*/
connect(displayCode) {
this.displayCode = displayCode;
let options = this.createMqttOptions();
let willMessage = this.createMySelfWill(displayCode, this.clientId);
let topic;
if (displayCode <= 0) {
// 遗嘱消息不能使用通配符
topic = Utils.getTopicPrefix(MsgType.WILL);
}
else {
topic = Utils.getTopicPrefix(MsgType.WILL) + displayCode;
}
// set will message
options.willTopic = topic;
options.willMessage = this.parser.toJson(willMessage);
options.willQoS = willMessage.getQoS();
options.isWillRetained = willMessage.isRetained();
// connect
this.connectWithOptions(options);
this.subscribeInterestTopic(displayCode);
}
connectWithOptions(options) {
this.client?.connect(options);
this.client?.setCallback(this);
this.isConnected = true;
}
createMqttOptions() {
let options = new MQTTConnectOption();
options.userName = this.getConfig().getUserName();
options.password = this.getConfig().getPassWord();
options.isCleanSession = this.getConfig().isCleanSession();
options.keepAliveInterval = this.getConfig().getKeepAlive();
options.connectionTimeout = this.getConfig().getConnectTimeout();
return options;
}
publish(displayCode, ymsMessage) {
ymsMessage.timestamp = Date.now();
ymsMessage.senderClientId = this.clientId;
this.client?.publish(Utils.getTopicPrefix(ymsMessage.msgType) + displayCode, this.parser.toJson(ymsMessage), ymsMessage.getQoS(), ymsMessage.isRetained());
}
disconnect(displayCode) {
return new Promise((resolve, reject) => {
this.unsubscribeAllTopics(displayCode);
this.client?.disconnect()
.then(() => {
this.isConnected = false;
resolve("MQTT断连成功");
})
.catch(reject);
});
}
// override
connectionLost(cause) {
SDKLog.e(this.TAG, cause);
this.isConnected = false;
this.onConnectionLost(cause);
}
// override
connectComplete(reconnect, serverURI) {
this.isConnected = true;
// 如果MQTT实现库内部会尝试自动重连,则在此响应自动重连成功后的回调,并再次进行主题订阅
if (reconnect) {
this.subscribeInterestTopic(this.displayCode);
}
}
// override
messageArrived(topic, message) {
SDKLog.i(this.TAG, "message arriavd, topic = " + topic);
let ymsMessage = this.parser.parse(message);
if (null === ymsMessage || undefined === ymsMessage)
return;
if (this.isMessageFromSelf(ymsMessage)) {
return;
}
if (!this.isMessageForMe(ymsMessage)) {
return;
}
if (this.isMessageExpired(topic, ymsMessage)) {
return;
}
switch (ymsMessage.msgType) {
case MsgType.WILL:
this.onWillMessageArrived(ymsMessage);
break;
case MsgType.REPORT:
this.onDisplayReportMessageArrived(ymsMessage);
break;
case MsgType.CAST:
this.onCastSessionMessageArrived(ymsMessage);
break;
case MsgType.DATA:
this.onDataMessageArrived(ymsMessage);
break;
case MsgType.ACCOUNT:
this.onUserHasBeenKickedMessageArrived(ymsMessage);
break;
case MsgType.BIND_DEVICE:
this.onAccountBindDeviceMessageArrived(ymsMessage);
break;
}
}
isMessageExpired(topic, message) {
// 如果是will遗嘱消息,则不做过期判断,直接返回未过期
if (MsgType.WILL === message.msgType) {
return false;
}
// 判断message的topic是否已经缓存在map,没有则进行首次添加
if (0 === this.messageTimestampOfSenderUnderTopics.size ||
!this.messageTimestampOfSenderUnderTopics.has(topic)) {
let firstTimeOfTopic = new Map();
this.messageTimestampOfSenderUnderTopics.set(topic, firstTimeOfTopic);
}
// 取对应topic的value,就是这个topic下所有发送端设备上一次发送消息的时间戳map
let messageTimestampOfSender = this.messageTimestampOfSenderUnderTopics.get(topic);
// 判断此clientId设备是否已经缓存上次时间戳,没有则进行首次添加
if (0 === messageTimestampOfSender.size ||
!messageTimestampOfSender.has(message.senderClientId)) {
// 首次添加,则将时间戳设置为0,表示第一次收到此clientId设备的消息
messageTimestampOfSender.set(message.senderClientId, 0);
}
// 取此clientId设备对应的上次消息时间戳,进行判断本次时间戳是否比上一次新,不是则标识为过期消息
let lastMessageTimestamp = messageTimestampOfSender.get(message.senderClientId);
let expired = (undefined === lastMessageTimestamp) ? true : (message.timestamp <= lastMessageTimestamp);
// 如果不是过期消息,则刷新时间戳缓存
if (!expired) {
lastMessageTimestamp = message.timestamp;
messageTimestampOfSender.set(message.senderClientId, lastMessageTimestamp);
this.messageTimestampOfSenderUnderTopics.set(topic, messageTimestampOfSender);
}
return expired;
}
getClient() {
return this.client;
}
getConfig() {
return this.config;
}
}
//# sourceMappingURL=MQTTLogic.js.map