import MqttMessage from "org.eclipse.paho.client.mqttv3.MqttMessage"; import MqttException from "org.eclipse.paho.client.mqttv3.MqttException"; import MqttConnectOptions from "org.eclipse.paho.client.mqttv3.MqttConnectOptions"; import MqttCallbackExtended from "org.eclipse.paho.client.mqttv3.MqttCallbackExtended"; import IMqttToken from "org.eclipse.paho.client.mqttv3.IMqttToken"; import IMqttMessageListener from "org.eclipse.paho.client.mqttv3.IMqttMessageListener"; import IMqttDeliveryToken from "org.eclipse.paho.client.mqttv3.IMqttDeliveryToken"; import IMqttActionListener from "org.eclipse.paho.client.mqttv3.IMqttActionListener"; import DisconnectedBufferOptions from "org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions"; import MqttAndroidClient from "info.mqtt.android.service.MqttAndroidClient"; import QoS from "info.mqtt.android.service.QoS"; import MqttCallback from "org.eclipse.paho.client.mqttv3.MqttCallback"; import Kotlin from 'kotlin.jvm.internal.Intrinsics.Kotlin'; import Context from 'android.content.Context'; import Intent from 'android.content.Intent'; import MqttService from 'org.eclipse.paho.android.service.MqttService'; import Service from 'android.app.Service'; import IBinder from 'android.os.IBinder'; import Build from 'android.os.Build'; 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" // // mqtt测试服务器 // https://console.hivemq.cloud/ // https://github.com/hannesa2/paho.mqtt.android/blob/master/extendedSample/src/main/java/info/mqtt/android/extsample/MainActivity.kt // let context = UTSAndroid.getAppContext()! as Context // let serviceIntent = new Intent(UTSAndroid.getUniActivity()!, UTSAndroid.getJavaClass(MqttService)); // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // context.startForegroundService(serviceIntent); // 对于 Android Oreo 及以上版本 // } else { // context.startService(serviceIntent); // 对于 Android Oreo 以下版本 // } export class xMqtt { mqtt : MqttAndroidClient | null = null; mqttConnectOptions : MqttConnectOptions | null = null; connectStatus : CONNECT_STATUS = 'wait' events = new Map(); constructor() { } /** * @param ulr {string} 连接地址 * @param clientIdStr {string} 客户端id * @param username {string|null} 用户名称,如果不需要,设置为null即可 * @param password {string|null} 登录密码,如果不需要,设置为null即可 */ create(opts : MQTT_CONNECT_OPTS) : xMqtt { let serverUri = opts.protocol + opts.server + ":" + opts.port.toString() + opts.path let clientId = opts.clientId this.mqttConnectOptions = new MqttConnectOptions() as MqttConnectOptions; if (this.mqttConnectOptions == null) return this; // 失败时,是否自动连接服务器。 this.mqttConnectOptions!.isAutomaticReconnect = opts.reconnect // 连接时是否清除会话 this.mqttConnectOptions!.isCleanSession = false //超时 this.mqttConnectOptions!.connectionTimeout = (opts.timeout * 100).toInt() //活跃间隔 this.mqttConnectOptions!.setKeepAliveInterval(opts.keepAliveInterval.toInt()) // 帐号名称 if (opts.userName != '') { this.mqttConnectOptions!.setUserName(opts.userName!) } // 帐号密码 if (opts.passWord != null) { this.mqttConnectOptions!.setPassword(opts.passWord!.toCharArray()) } this.mqtt = new MqttAndroidClient(UTSAndroid.getAppContext()!, serverUri, clientId); this.connectStatus = 'wait' return this; } /** * @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) } }) } /** * 连接mqtt服务器 */ connect() : xMqtt { let t = this; if (this.mqtt == null) return this; try { class mqttCallBack implements MqttCallback { // 连接丢失 override connectionLost(cause : kotlin.Throwable | null) { // console.log('Mqtt:Connection lost') t.connectStatus = 'dissconnect' t.buildCallEvents('dissconnect', null, '连接断开') } // 首次连接时收到的消息 override messageArrived(topic : string, message : MqttMessage) { // console.log('Mqtt:', new String(message.getPayload())) } // 发布的消息是否已到达 override deliveryComplete(token : IMqttDeliveryToken) { // console.log('Message delivered') } } class connectListen implements IMqttActionListener { // 连接成功 override onSuccess(asyncActionToken : IMqttToken) { // console.log('Connected to MQTT broker',asyncActionToken) t.connectStatus = 'open' t.buildCallEvents('open', null, '连接成功') } // 连接失败 override onFailure(asyncActionToken : IMqttToken, exception : kotlin.Throwable) { // console.log('Connected to MQTT Failed', exception) t.connectStatus = 'error' t.buildCallEvents('error', null, '连接失败') } } this.connectStatus = 'opening' this.mqtt!.setCallback(new mqttCallBack()); this.mqtt!.connect(this.mqttConnectOptions!, null, new connectListen()); } catch (e : kotlin.Throwable) { //TODO handle the exception } 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 mqttMessage = new MqttMessage(message.toByteArray()); // 设置消息服务质量等级0,1,2 mqttMessage.setQos(msg.qos.toInt()); // 设置消息是否需要被服务器持久化 mqttMessage.setRetained(msg.retained); class messageListen implements IMqttActionListener { override onSuccess(asyncActionToken : IMqttToken) { console.log(topic, '发布成功') call(true) } override onFailure(asyncActionToken : IMqttToken, exception : kotlin.Throwable) { console.log(topic, '发布失败', exception) call(false) } } this.mqtt!.publish(topic, mqttMessage, null, new messageListen()); return this; } /** * 订阅 * @param data {MQTT_SUBSCRIBE[]} 订阅的消息数组 */ subscribe(data : MQTT_SUBSCRIBE[]) : xMqtt { let t = this; if (this.mqtt == null) return this; let msglisten = [] as IMqttMessageListener[]; let tops = [] as string[] let qos = new IntArray(data.length.toInt()) for (let i = 0; i < data.length; i++) { class messageListen implements IMqttMessageListener { override messageArrived(topic : string, message : MqttMessage) { // 处理消息 let data = message.getPayload(); t.buildCallEvents('message', topic, String(data)) } } msglisten.push(new messageListen()) tops.push(data[i].topic) qos.set(i.toInt(), data[i].qos.toInt()) } let token : IMqttToken = this.mqtt!.subscribe(tops.toTypedArray(), qos, msglisten.toTypedArray()) if (token.isComplete()) { console.log("订阅成功") } return this; } /** * 取消订阅 * @param topics {string[]} 主题数组 */ unsubscribe(topics : string[]) : xMqtt { let t = this; if (this.mqtt == null || topics.length == 0) return this; this.mqtt!.unsubscribe(topics.toTypedArray()) return this; } /** * 断开连接 */ disconnect() : xMqtt { if (this.mqtt == null) return this; this.mqtt!.disconnect() return this; } }