使用mqttv3.MqttClient建立Mqtt连接

  1. 引入mqtt库
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0'
  1. 创建连接
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}"
    }
}
  1. 连接成功后订阅消息处理
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.")
        }
    }

  1. 类代码
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")
        }
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值