1. 程式人生 > >MQTT協議實現Android中的訊息收發

MQTT協議實現Android中的訊息收發

前言

MQTT(Message Queuing Telemetry Transport,訊息佇列遙測傳輸),基於釋出/訂閱正規化的訊息協議,是一種極其簡單和輕量級的訊息協議,專為受限裝置和低頻寬、高延遲或不可靠的網路設計。今天主要說明一下MQTT協議在Android中進行訊息的收發應用,關於MQTT協議的基礎內容請參考之前介紹的 MQTT協議 相關內容。

效果

使用前先檢視一下簡單的效果圖,MQTT相關的連線、訂閱,傳送及接收:

使用過程

  1. 依賴新增
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'

實際使用中發現,如果僅用第一條依賴也是能夠實現我們所需要的的訊息收發功能的,其中MqttClient類實現了MQTT相關的連線、訂閱、傳送及接收功能,第二條依賴是基於MqttClient針對Android客戶端進行封裝了MqttAndroidClient進行使用,其中實現了Android相關的廣播、服務相關內容。

使用中如果採用的是Androidx開發環境,還需要新增如下依賴,否則MqttAndroidClient服務中會找不到本地廣播服務,導致無法執行使用。

implementation 'androidx.legacy:legacy-support-v4:1.0.0'
  1. 許可權新增
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
  1. 服務新增
<service android:name="org.eclipse.paho.android.service.MqttService"/>

這裡我們主要介紹MqttClient類實現的MQTT協議訊息的收發,而進一步封裝的MqttAndroidClient和其使用過程基本類似,想要檢視其具體使用,可跳轉對應Demo連結獲取詳細內容。

  1. 初始化MQTT客戶端內容,代理伺服器broker選用的 HiveMQ公共代理 來實現:
public void initClient() {
    try {
        MemoryPersistence persistence = new MemoryPersistence();
        // 設定唯一客戶端ID
        clientId = clientId + System.currentTimeMillis();
        //設定訂閱方訂閱的Topic集合,遵循MQTT的訂閱規則,可以是多級Topic集合
        final String topicFilter = topic;
        //服務質量,對應topicFilter
        final int qos = 0;
        //建立客戶端
        sampleClient = new MqttClient(broker, clientId, persistence);
        //配置回撥函式
        sampleClient.setCallback(new MqttCallbackExtended() {
            @Override
            public void connectComplete(boolean reconnect, String serverUri) {
                setTextInfo("connectComplete: " + serverUri);
                try {
                    //連線成功,需要上傳客戶端所有的訂閱關係
                    sampleClient.subscribe(topicFilter, qos);
                } catch (MqttException e) {
                    setTextInfo("subscribeException: " + e.getMessage());
                }
            }

            @Override
            public void connectionLost(Throwable cause) {
                setTextInfo("connectionLostException: " + cause.getMessage());
            }

            @Override
            public void messageArrived(String topic, MqttMessage message) {
                setTextInfo("messageArrived:" + new String(message.getPayload()));
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {
                setTextInfo("deliveryComplete");
            }
        });
        //建立連線選擇
        MqttConnectOptions connOpts = createConnectOptions(userName, passWord);
        setTextInfo("Connecting to broker: " + broker);
        //建立服務連線
        sampleClient.connect(connOpts);
    } catch (MqttException me) {
        setTextInfo("initException: " + me.getMessage());
    }
}
  1. 建立連線選擇如下,可設定使用者名稱、密碼:
private MqttConnectOptions createConnectOptions(String userName, String passWord) {
    MqttConnectOptions connOpts = new MqttConnectOptions();
    connOpts.setCleanSession(true);
    connOpts.setUserName(userName);
    connOpts.setPassword(passWord.toCharArray());
    connOpts.setAutomaticReconnect(true);
    // 設定連線超時時間, 單位為秒,預設30
    connOpts.setConnectionTimeout(30);
    // 設定會話心跳時間,單位為秒,預設20
    connOpts.setKeepAliveInterval(20);
    return connOpts;
}
  1. 訊息釋出:
public void publishMsg() {
    String content = mEtMessage.getText().toString().trim();
    if (TextUtils.isEmpty(content)) {
        content = "Hello MQTT ";
    }
    //此處訊息體需要傳入byte陣列
    MqttMessage message = new MqttMessage(content.getBytes());
    //設定質量級別
    message.setQos(0);
    try {
        if (sampleClient != null && sampleClient.isConnected()) {
            /*
             * 訊息傳送到某個主題Topic,所有訂閱這個Topic的裝置都能收到這個訊息。
             * 遵循MQTT的釋出訂閱規範,Topic也可以是多級Topic。此處設定了傳送到一級Topic。
             */
            sampleClient.publish(topic, message);
            setTextInfo("publishMsg: " + message);
        }
    } catch (MqttException e) {
        setTextInfo(" publishException: " + e.getMessage());
    }
}
  1. 連線斷開:
public void disconnect() {
    try {
        sampleClient.disconnect();
    } catch (MqttException e) {
        setMqttMessage("disconnectException: " + e.getMessage());
    }
}

MQTT協議實現Android中的訊息收發就到這裡了,內容已上傳至Github開發記錄,歡迎點選查閱及Star,我也會繼續補充其它有用的知識及例子在專案上。

歡迎點贊/評論,你們的贊同和鼓勵是我寫作的最大動力!

關注公眾號:幾圈年輪,檢視更多有趣的技術、工具、閒言、資源。