Files
hospital-rescue-app-v2/uni_modules/x-mqtt-s/utssdk/app-ios/back
T
2026-09-24 16:25:22 +08:00

285 lines
8.3 KiB
Plaintext

import {
CONNECT_STATUS, MQTT_EVENT_TYPE, MQTT_EVENT_CALL, MQTT_EVENT_PUBLISH, MQTT_SUBSCRIBE, MQTT_EVENTS_CALL,
MQTT_PUBLISH_TOPIC, MQTT_CONNECT_OPTS
} from "../interface.uts"
import {
CocoaMQTT, CocoaMQTTWebSocket, CocoaMQTT5Delegate, CocoaMQTT5, MqttConnectProperties,
CocoaMQTTDISCONNECTReasonCode,
CocoaMQTTAUTHReasonCode,
MqttDecodeUnsubAck,
MqttDecodeSubAck,
CocoaMQTT5Message,
MqttDecodePublish,
MqttDecodePubAck,
MqttDecodePubRec,
MqttDecodeConnAck,
CocoaMQTTCONNACKReasonCode,
CocoaMQTTConnState,
CocoaMQTTQoS, MqttPublishProperties, CocoaMQTTError, CocoaMQTTMessage
} from "CocoaMQTT"
// https://github.com/anatoliykant/SwiftMQTT
import { UInt16 } from 'Swift';
import { Bundle, CFArray, SecPKCS12Import } from 'Foundation';
import { kCFStreamSSLCertificates } from 'CFNetwork';
import { NSObject } from 'ObjectiveC';
// https://github.com/emqx/CocoaMQTT
// https://cocoapods.org/pods/CocoaMQTT
// 文档:https://www.emqx.com/en/blog/ios-mqtt5-client
class MQTTDELETED implements CocoaMQTT5Delegate {
// 授权状态
mqtt5(mqtt5 : CocoaMQTT5, @argumentLabel("didReceiveAuthReasonCode") reasonCode : CocoaMQTTAUTHReasonCode) {
console.log(4)
}
// 连接丢失状态
mqtt5(mqtt5 : CocoaMQTT5, @argumentLabel("didReceiveDisconnectReasonCode") reasonCode : CocoaMQTTDISCONNECTReasonCode) {
console.log(3)
}
// 取消订阅 MqttDecodeUnsubAck
mqtt5(mqtt5 : CocoaMQTT5, @argumentLabel("didUnsubscribeTopics") topics : string[], unsubAckData : any) {
console.log(2)
}
// 订阅 MqttDecodeSubAck
mqtt5(mqtt5 : CocoaMQTT5, @argumentLabel("didSubscribeTopics") success : NSDictionary, failed : string[], subAckData : any) {
console.log(1)
}
// 收到消息 MqttDecodePublish
mqtt5(mqtt5 : CocoaMQTT5, @argumentLabel("didReceiveMessage") message : CocoaMQTT5Message, id : number, publishData : any) {
console.log(8)
}
// 重复发送消息 MqttDecodePubRec
mqtt5(mqtt5 : CocoaMQTT5, @argumentLabel("didPublishRec") id : number, pubRecData : any) {
console.log(8)
}
// 推送消息异常 MqttDecodePubAck
mqtt5(mqtt5 : CocoaMQTT5, @argumentLabel("didPublishAck") id : number, pubAckData : any) {
console.log(8)
}
// 推送消息
mqtt5(mqtt5 : CocoaMQTT5, @argumentLabel("didPublishMessage") message : CocoaMQTT5Message, id : number) {
console.log(8)
}
// 推送消息 MqttDecodeConnAck
mqtt5(mqtt5 : CocoaMQTT5, @argumentLabel("didConnectAck") ack : CocoaMQTTCONNACKReasonCode, connAckData : any) {
console.log(8)
}
}
let xmqtt : CocoaMQTT | null = null
const connectDeleted : MQTTDELETED | null = null;
export class xMqtt {
mqtt : CocoaMQTT | null = null;
mqttConnectOptions : MqttConnectProperties | null = null;
connectStatus : CONNECT_STATUS = 'wait'
events = new Map<string, MQTT_EVENTS_CALL>();
constructor() { }
/**
* @param type {MQTT_EVENT_TYPE} 事件名称
* @param call {MQTT_EVENT_CALL} 事件回调
*/
@UTSJS.keepAlive
addEventListener(type : MQTT_EVENT_TYPE, call : MQTT_EVENT_CALL) : string {
let id = Date.now().toString() + (Math.random() * 100).toString()
this.events.set(id,
{
type,
value: call
} as MQTT_EVENTS_CALL
)
return id;
}
/**
* @param id {string} addEventListener返回的事件id
*/
removeEventListener(id : string) : xMqtt {
this.events.delete(id)
return this;
}
private buildCallEvents(type : MQTT_EVENT_TYPE, toppic : string | null, str : string) {
this.events.forEach((value : MQTT_EVENTS_CALL, key : string) => {
if (value.type == type) {
value.value(type, toppic, str)
}
})
}
create(opts : MQTT_CONNECT_OPTS) : xMqtt {
let t = this;
let clientID = opts.clientId!
let websocket = CocoaMQTTWebSocket(uri = opts.path)
let mqtt5 = new CocoaMQTT(clientID = clientID, host = opts.server, port = opts.port!.toUInt16(), socket = websocket)
mqtt5.willMessage = new CocoaMQTTMessage(topic = "/will", string = "dieout")
// let connectProperties = MqttConnectProperties()
// connectProperties.topicAliasMaximum = 0
// connectProperties.sessionExpiryInterval = 0
// connectProperties.receiveMaximum = 100
// connectProperties.maximumPacketSize = 5000
// mqtt5.connectProperties = connectProperties
mqtt5.username = opts.userName
mqtt5.password = opts.passWord
mqtt5.keepAlive = opts.keepAliveInterval.toUInt16()
mqtt5.enableSSL = opts.useSSL
mqtt5.autoReconnect = opts.reconnect
mqtt5.allowUntrustCACertificate = true
let sslCart = opts.certName==null?"":(opts.certName)
let isP12 = false;
// let sslSettings = new Map<string, NSObject>()
if (sslCart != "" && opts.useSSL) {
isP12 = sslCart.lastIndexOf(".p12") > -1;
if (isP12) {
let passwordSsl = opts.certPassword == null ? "" : (opts.certPassword)
if (passwordSsl != "") {
let crtpath = Bundle.main.path(forResource = String(sslCart.substring(0, sslCart.lastIndexOf("."))), ofType = "p12")
let temsslSettings = getClientCertFromP12File(resourcePath = crtpath == null ? "" : (crtpath!), certPassword = String(passwordSsl))
if (temsslSettings != null) {
mqtt5.sslSettings = temsslSettings!
} else {
console.error("提供的P12证书有误或者文件不存在.")
}
} else {
console.error("提供了p12证书,但未提供证书密码.")
}
} else {
let crtpath = Bundle.main.path(forResource = String(sslCart.substring(0, sslCart.lastIndexOf("."))), ofType = "crt")
// ca文件.
let temsslSettings = getClientCertFromCrtFile(resourcePath = crtpath == null ? "" : (crtpath!))
if (temsslSettings != null) {
// console.log(temsslSettings)
mqtt5.sslSettings = temsslSettings!
} else {
console.error("提供的Ca证书有误或者文件不存在.")
}
}
}
mqtt5.cleanSession = true
// mqtt5.delegate = new MQTTDELETED()
mqtt5.didDisconnect = (client : CocoaMQTT, errorcode ?: any) => {
let code = errorcode as CocoaMQTTError | null
if (errorcode instanceof CocoaMQTTError) {
t.connectStatus = 'error'
t.buildCallEvents('error', null, '连接错误')
} else {
t.connectStatus = 'error'
t.buildCallEvents('error', null, '地址错误,或者没有网络。')
}
}
mqtt5.didConnectAck = (client : CocoaMQTT, cack ?: any) => {
t.connectStatus = 'open'
t.buildCallEvents('open', null, '已连接')
console.log('success')
}
mqtt5.didChangeState = (client : CocoaMQTT, state : CocoaMQTTConnState) => {
if (state == CocoaMQTTConnState.connecting) {
console.log('连接中')
}
if (state == CocoaMQTTConnState.connected) {
console.log('连接成功')
}
if (state == CocoaMQTTConnState.disconnected) {
console.log('连接失败')
t.connectStatus = 'dissconnect'
t.buildCallEvents('dissconnect', null, '已断开连接')
}
}
mqtt5.didReceiveMessage = (client : CocoaMQTT, message : CocoaMQTTMessage, id : UInt16) => {
let topic = message.topic
let msg = message.string
t.connectStatus = 'message'
t.buildCallEvents('message', topic, msg == null ? '' : (msg!))
}
this.mqtt = mqtt5;
return this;
}
connect() : xMqtt {
if (this.mqtt == null) return this;
this.mqtt!.connect()
return this;
}
/**
* 推送消息
* @param call {MQTT_EVENT_PUBLISH}
*/
publish(msg : MQTT_PUBLISH_TOPIC, call : MQTT_EVENT_PUBLISH) : xMqtt {
if (this.mqtt == null) return this;
let topic = msg.topic
let message = msg.message
let qos : CocoaMQTTQoS = CocoaMQTTQoS.qos0
if (msg.qos == 1) {
qos = CocoaMQTTQoS.qos1
} else if (msg.qos == 2) {
qos = CocoaMQTTQoS.qos2
}
this.mqtt!.publish(new CocoaMQTTMessage(topic = topic!, string = message!, qos = qos, retained = msg.retained))
call(true)
return this;
}
/**
* 订阅
* @param data {MQTT_SUBSCRIBE[]} 订阅的消息数组
*/
subscribe(data : MQTT_SUBSCRIBE[]) : xMqtt {
let t = this;
if (this.mqtt == null) return this;
for (let i = 0; i < data.length; i++) {
let qos : CocoaMQTTQoS = CocoaMQTTQoS.qos0
if (data[i].qos == 1) {
qos = CocoaMQTTQoS.qos1
} else if (data[i].qos == 2) {
qos = CocoaMQTTQoS.qos2
}
this.mqtt!.subscribe(data[i].topic, qos = qos)
}
return this;
}
/**
* 取消订阅
* @param topics {string[]} 主题数组
*/
unsubscribe(topics : string[]) : xMqtt {
if (this.mqtt == null) return this;
for (let i = 0; i < topics.length; i++) {
this.mqtt!.unsubscribe(topics[i])
}
return this;
}
/**
* 断开连接
*/
disconnect() : xMqtt {
if (this.mqtt == null) return this;
this.mqtt!.disconnect()
return this;
}
}