Android使用MQTT实现消息发布与订阅

关于MQTT

MQTT中文文档

MQTT GitHub

MQTT协议规范

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和制动器(比如通过Twitter让房屋联网)的通信协议。

MQTT应用

通过MQTT协议,目前已经扩展出了数十个MQTT服务器端程序,可以通过PHP,JAVA,Python,C,C#等系统语言来向MQTT发送相关消息。国内很多企业都广泛使用MQTT作为Android手机客户端与服务器端推送消息的协议,随着移动互联网的发展,MQTT由于开放源代码,耗电量小等特点,将会在移动消息推送领域会有更多的贡献,在物联网领域,传感器与服务器的通信,信息的收集,MQTT都可以作为考虑的方案之一。在未来MQTT会进入到我们生活的各各方面。

MQTT特点

1、使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;

2、对负载内容屏蔽的消息传输;

3、使用 TCP/IP 提供网络连接;

4、有三种消息发布服务质量:“至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。“至少一次”,确保消息到达,但消息重复可能会发生。“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。

5、小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;

6、使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制; 

MQTT Android中使用

MainActivity代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private String mClintId;
    public static MqttClient mMqClint;
    public MqttConnectOptions mMqttConnectOptions;
    private ScheduledExecutorService scheduler;
    private final static String TAG = MainActivity.class.getSimpleName();
    private Button mBtSub,mBtSend;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtSub = this.findViewById(R.id.bt_sub);
        mBtSend = this.findViewById(R.id.bt_send);
        mBtSend.setOnClickListener(this);
        mBtSub.setOnClickListener(this);
        initMqtt();
    }

    /**
     * 初始化mqtt
     */
    private void initMqtt() {
        StringBuffer sb = new StringBuffer();
        sb.append(System.currentTimeMillis());
        sb.append(RandomStringUtil.getInstance().RandomStringUtil());
        mClintId = sb.toString();
        try {
            mMqClint = new MqttClient(Constant.HOST, mClintId, new MemoryPersistence());
            mMqttConnectOptions = new MqttConnectOptions();
            //清除缓存
            mMqttConnectOptions.setCleanSession(true);
            //设置用户名
            mMqttConnectOptions.setUserName(Constant.USERNAME);
            //设置用户密码
            mMqttConnectOptions.setPassword(Constant.USERPASSWORD.toCharArray());
            // 设置超时时间,单位:秒
            mMqttConnectOptions.setConnectionTimeout(10);
            // 心跳包发送间隔,单位:秒
            mMqttConnectOptions.setKeepAliveInterval(20);
            //设置回调
            mMqClint.setCallback(new PushCallBack());
            //MqttTopic topic = client.getTopic(ConnectUrl.SUBSCRIBETOPIC);
            //options.setWill(topic, "close".getBytes(), 0, true);
            //订阅消息
            connect();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }


    /**
     * mqtt链接
     */
    public void connect() {
        ThreadTask.getInstance().executorOtherThread(new Runnable() {
            @Override
            public void run() {
                try {
                    if (mMqClint != null) {
                        //开始链接
                        mMqClint.connect(mMqttConnectOptions);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, ThreadTask.ThreadPeriod.PERIOD_HIGHT);
    }

    /**
     * 定时检查mqtt是否连接
     */
    private void startReconnect() {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                if (!mMqClint.isConnected()) {
                    connect();
                }
            }
        }, 0 * 1000, 10 * 1000, TimeUnit.MILLISECONDS);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.bt_sub:
                if (mMqClint.isConnected()){
                    try {
                        mMqClint.subscribe(Constant.SUBSCRIBETOPIC,0);
                    } catch (MqttException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case R.id.bt_send:
                MqttTopic topic = mMqClint.getTopic(Constant.SENDPIC);
                MqttMessage message = new MqttMessage();
                message.setPayload("要发送的消息".getBytes());
                try {
                    topic.publish(message);
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    public static class PushCallBack implements MqttCallback {

        @Override
        public void connectionLost(Throwable throwable) {
            Log.i(TAG, "connectionLost: 链接丢失");
        }

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            Log.i(TAG, "messageArrived: 接收消息回调");
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {
            Log.i(TAG, "deliveryComplete: 发布消息回调");
        }

      
    }

}

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context="cn.puming.struggle.mqttdemo.MainActivity">

    <Button
        android:id="@+id/bt_sub"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:text="开始订阅!"/>

    <Button
        android:id="@+id/bt_send"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:text="开始订阅!"
      />

</LinearLayout>

Manifest申请网络权限:

<uses-permission android:name="android.permission.INTERNET"/>
Demo下载地址:https://download.csdn.net/download/zhuhuitao_struggle/10421853

猜你喜欢

转载自blog.csdn.net/zhuhuitao_struggle/article/details/80330387