Android使用mqtt协议实现消息收发

Android使用mqtt协议实现消息收发

最近项目中需要用到MQTT协议,于是上网看了很多资料,照葫芦画瓢写了一个简单的Demo,将过程记录在此。

Mqtt是一个轻量级的消息传输协议,使用发布/订阅消息模式,使用起来非常方便。


准备工作

在开始敲代码之前,我们先把一些环境和工具装好,以便后续使用。

1. windows下搭建mqtt服务器

我选择的是搭建一个Apollo服务器,可以参考【MQTT】在Windows下搭建MQTT服务器 这篇博文,介绍得很详细。
1) 搭建JAVA环境,并配置好JAVA_HOME环境变量
2) 下载Apollo服务器文件并解压:官网下载
3)CMD环境下运行bin\apollo.cmd create mybroker,建立名为mybroker的实例,用户名和密码默认为admin-password
4)进入\mybroker\bin目录下,执行apollo-broker.cmd run
5)运行后可以通过浏览器访问https://127.0.0.1:61681/进入web后台管理页面

2.下载Eclipse Paho MQTT Utility

Eclipse Paho MQTT Utility是一个很实用的mqtt工具,点此进入官网下载
界面很友好,使用起来比较简单,教程连接:
https://jingyan.baidu.com/article/25648fc16b8e969191fd00be.html


配置工程

使用Android Studio建立一个MqttDemo工程,在build.gradle中添加

repositories {
    maven {
        url "https://repo.eclipse.org/content/repositories/paho-releases/"
    }
dependencies {
    ...
    compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
    compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'
}

添加权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

注册mqtt服务

<service android:name="org.eclipse.paho.android.service.MqttService" />

这里我们新建一个MqttManager类,该类主要提供建立mqtt连接、发布消息、订阅消息、接收消息等方法。

import android.content.Context;
import android.util.Log;
import android.webkit.WebMessagePort;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

public class MqttManager {
    public static final String TAG = MqttManager.class.getSimpleName();

    private String host = "tcp://192.168.232.204:61613";
    private String userName = "admin";
    private String passWord = "password";
    private String clientId = "";

    private static MqttManager mqttManager = null;
    private MqttClient client;
    private MqttConnectOptions connectOptions;

    public MqttManager(Context context){
        clientId = MqttClient.generateClientId();
    }

    public MqttManager getInstance(Context context){
        if(mqttManager == null){
            mqttManager = new MqttManager(context);
        }else{
            return mqttManager;
        }
        return null;
    }

    public void connect(){
        try{
            client = new MqttClient(host,clientId,new MemoryPersistence());
            connectOptions = new MqttConnectOptions();
            connectOptions.setUserName(userName);
            connectOptions.setPassword(passWord.toCharArray());
            client.setCallback(mqttCallback);
            client.connect(connectOptions);
        }catch (MqttException e){
            e.printStackTrace();
        }
    }

    public void subscribe(String topic,int qos){
        if(client != null){
            int[] Qos = {qos};
            String[] topic1 = {topic};
            try {
                client.subscribe(topic1, Qos);
                Log.d(TAG,"订阅topic : "+topic);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }

    public void publish(String topic,String msg,boolean isRetained,int qos) {
        try {
            if (client!=null) {
                MqttMessage message = new MqttMessage();
                message.setQos(qos);
                message.setRetained(isRetained);
                message.setPayload(msg.getBytes());
                client.publish(topic, message);
            }
        } catch (MqttPersistenceException e) {
            e.printStackTrace();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    private MqttCallback mqttCallback = new MqttCallback() {
        @Override
        public void connectionLost(Throwable cause) {
            Log.i(TAG,"connection lost");
        }

        @Override
        public void messageArrived(String topic, MqttMessage message){
            Log.i(TAG,"received topic : " + topic);
            String payload = new String(message.getPayload());
            Log.i(TAG,"received msg : " + payload);
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {
            Log.i(TAG,"deliveryComplete");
        }
    };

}

这里host就是前面搭建的mqtt服务器的IP地址和端口,userName和passWord则是默认的。clientId是mqtt客户端的唯一标识符,如果网络中有多个客户端,可以通过clientId来辨别。这里使用generateClientId方法自动生成id。

当然,这个类只能简单地测试消息订阅和收发,还需要后续完善。

接下来在MainActivity添加使用MqttManager的代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mqttManager = new com.test.mqttdemo.MqttManager(this);
    mqttManager.connect();
    mqttManager.subscribe("/testSubscribe",0);
    mqttManager.publish("/testPublish","hello mqtt",false,0);

    setContentView(R.layout.activity_main);
}

app启动后即会订阅/testSubscribe主题,并发布以/testPublish为topic,hello mqtt为payload的消息。

怎么测试程序是否收发成功了呢?我们在Eclipse Paho MQTT Utility中新建一个连接,服务器url与代码中一样:tcp://192.168.232.204:61613,这时运行我们的程序,右边的历史记录框中会显示接收到消息。
Android使用mqtt协议实现消息收发_第1张图片
再通过发布一个主题为/testSubscribe的消息,在Android Studio的Logcat中即可看到输出的消息主题和内容。

至此,一个简单的mqtt消息收发程序就完成了。

你可能感兴趣的:(Android)