237 lines
7.9 KiB
Plaintext
237 lines
7.9 KiB
Plaintext
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"
|
|
|
|
|
|
// <service android:name="org.eclipse.paho.android.service.MqttService"></service>
|
|
|
|
// 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<string, MQTT_EVENTS_CALL>();
|
|
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;
|
|
}
|
|
|
|
} |