1
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
|
||||
package="io.dcloud.uni_modules.xMqttS">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
</manifest>
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"minSdkVersion": "21",
|
||||
"dependencies":[
|
||||
"com.github.hannesa2:paho.mqtt.android:4.2.4"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user