- 引入mqtt库
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0'
- 创建连接
mqttConnectionOptions = MqttConnectOptions()
mqttConnectionOptions.isCleanSession = true
mqttConnectionOptions.connectionTimeout = 10
mqttConnectionOptions.keepAliveInterval = 10
mqttConnectionOptions.isAutomaticReconnect = true
mqttConnectionOptions.sslHostnameVerifier = HostnameVerifier { hostname, session -> true }
if (cfg.username.isNotEmpty()) {
mqttConnectionOptions.userName = cfg.username
}
if (cfg.password.isNotEmpty()) {
mqttConnectionOptions.password = cfg.password.toCharArray()
}
mqttConnectionOptions.setWill("app/uav/xiaoMI/topo_changed",
DEAD_MSG.toByteArray(),
DefaultQos, false)
val clientId = cfg.client_id // BLSession.phoneMacAddr
val persistence = MemoryPersistence()
mqttClient = MqttClient(brokerUrl, clientId, persistence).apply {
mqttCallback = MyMqttCallback()
this.setCallback(mqttCallback)
doClientConnection(this)
}
连接需要的参数:
class MqttConnectInfo {
var url:String = ""
var client_id: String = ""
var username: String = ""
var password: String = ""
override fun toString(): String {
return "{url: $url, client_id: $client_id, username: $username, password: $password}"
}
}
- 连接成功后订阅消息处理
private fun doClientConnection(client: MqttClient) {
if (!client.isConnected && !isConnecting.get()) {
try {
isConnecting.set(true)
if (false) {
ApronMqttHelper.Companion.loadCrtKey(mqttConnectionOptions)
}
client.connect(mqttConnectionOptions)
BLLog.log2File(TAG, "连接成功,开始订阅消息...")
subscribeAll(client)
isConnecting.set(false)
} catch (e: Exception) {
BLLog.log2File(TAG, "doClientConnection 异常:${e},稍后重连...")
e.printStackTrace()
isConnecting.set(false)
// ApronMqttKeeper.notifyConnectFailed("连接失败: $e")
}
}
}
private fun subscribeAll(client: MqttClient) {
val mac = "48:1C:B9:7B:8C:B6"
if (mac.isNotEmpty()) {
val requestTopic = ApronMqttMsgType.Companion.REQUEST.replace("+", mac)
client.let {
it.subscribe(requestTopic, DefaultQos)
}
} else {
BLLog.log2File(TAG, "Something wrong! Mac is Empty.")
}
}
- 类代码
object LocalMqttManager {
private val TAG = LocalMqttManager::class.java.simpleName
private const val DefaultQos = 2
private val RETRY_DELAY = 5000L
@Volatile
private var mqttClient: MqttClient? = null
private lateinit var mqttConnectionOptions: MqttConnectOptions
private var mqttCallback = MyMqttCallback()
private val isConnecting = AtomicBoolean(false)
val DEAD_MSG = """ {"msg": "I am dead.oops!"} """
fun connectServer(mqttSv: MqttConnectInfo) {
val cfg = mqttSv
// "tcp://broker.emqx.io:1883"
// "wss://broker.emqx.io:8084"
// val defUrl = "ssl://192.168.0.56:8883"
val brokerUrl = ApronMqttHelper.Companion.getMqttUrl(cfg)
BLLog.log2File(TAG, "connectServer cfg: $cfg")
// if url changed
closeImmediately()
mqttConnectionOptions = MqttConnectOptions()
mqttConnectionOptions.isCleanSession = true
mqttConnectionOptions.connectionTimeout = 10
mqttConnectionOptions.keepAliveInterval = 10
mqttConnectionOptions.isAutomaticReconnect = true
mqttConnectionOptions.sslHostnameVerifier = HostnameVerifier { hostname, session -> true }
if (cfg.username.isNotEmpty()) {
mqttConnectionOptions.userName = cfg.username
}
if (cfg.password.isNotEmpty()) {
mqttConnectionOptions.password = cfg.password.toCharArray()
}
mqttConnectionOptions.setWill("app/uav/xiaoMI/topo_changed",
DEAD_MSG.toByteArray(),
DefaultQos, false)
val clientId = cfg.client_id // BLSession.phoneMacAddr
val persistence = MemoryPersistence()
mqttClient = MqttClient(brokerUrl, clientId, persistence).apply {
mqttCallback = MyMqttCallback()
this.setCallback(mqttCallback)
doClientConnection(this)
}
}
private fun closeImmediately() {
mqttCallback.setRecycled()
val client = mqttClient ?: return
ApronMqttHelper.Companion.closeMqttClient(client)
}
fun publish(topic: String, content: String) {
if (isConnected()) {
mqttClient?.publish(topic, content.toByteArray(), DefaultQos, false)
}
}
private fun doClientConnection(client: MqttClient) {
if (!client.isConnected && !isConnecting.get()) {
try {
isConnecting.set(true)
if (false) {
ApronMqttHelper.Companion.loadCrtKey(mqttConnectionOptions)
}
client.connect(mqttConnectionOptions)
BLLog.log2File(TAG, "连接成功,开始订阅消息...")
subscribeAll(client)
isConnecting.set(false)
} catch (e: Exception) {
BLLog.log2File(TAG, "doClientConnection 异常:${e},稍后重连...")
e.printStackTrace()
isConnecting.set(false)
// ApronMqttKeeper.notifyConnectFailed("连接失败: $e")
}
}
}
private fun subscribeAll(client: MqttClient) {
val mac = "48:1C:B9:7B:8C:B6"
if (mac.isNotEmpty()) {
val requestTopic = ApronMqttMsgType.Companion.REQUEST.replace("+", mac)
client.let {
it.subscribe(requestTopic, DefaultQos)
}
} else {
BLLog.log2File(TAG, "Something wrong! Mac is Empty.")
}
}
private fun isConnected(): Boolean {
return mqttClient?.isConnected ?: false
}
private class MyMqttCallback : MqttCallback {
@Volatile
private var recycled: Boolean = false
fun setRecycled() {
recycled = true
}
override fun connectionLost(p0: Throwable) {
if (recycled) {
return
}
BLLog.log2File(TAG, "connectionLost: Mqtt连接断开:${p0},即将重连!")
p0.printStackTrace()
// CommonUtils.runDelayed(RETRY_DELAY) { doClientConnection(mqttClient!!) }
// maybe url need to update.
// ApronMqttKeeper.notifyConnectFailed("Mqtt连接断开:${p0}")
}
override fun messageArrived(topic: String, message: MqttMessage) {
if (recycled) {
return
}
val msg = String(message.payload)
BLLog.i(TAG, "RECV $topic, $message")
// 处理接收到的消息 todo
// ApronMqttAcceptManager.onAccept(topic, msg)
}
override fun deliveryComplete(p0: IMqttDeliveryToken) {
BLLog.i(TAG, "deliveryComplete: $p0")
}
}
}
3335

被折叠的 条评论
为什么被折叠?



