1、关于MQTT简介

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议。它是一种发布/订阅,极其简单和轻量级的消息传递协议,专为受限设备和低带宽,高延迟或不可靠的网络而设计。它的设计思想是轻巧、开放、简单、规范,易于实现。这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器的通信(M2M)以及物联网环境。相对于XMPP,MQTT更加轻量级,并且占用的宽带低。

MQTT协议有以下特点:

  1. 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。
  2. 对负载内容屏蔽的消息传输。
  3. 使用 TCP/IP 提供网络连接。
  4. 有三种消息发布服务质量:
    • qos为0:“至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
    • qos为1:“至少一次”,确保消息到达,但消息重复可能会发生。这一级别可用于如下情况,你需要获得每一条消息,并且消息重复发送对你的使用场景无影响。
    • qos为2:“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
  5. 小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量。
    使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制。

2、MQTT协议的消息机制

  • 发布方(Publisher)将消息发送到 Broker(MQTT服务器);
  • Broker 接收到消息以后,检查下都有哪些订阅方订阅了此类消息,然后将消息发送到这些订阅方;
  • 订阅方(Subscriber)从 Broker 获取该消息。

android端实现:

1、在module的build.gradle文件中添加依赖

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

2、在 AndroidManifest.xml 添加限权

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

3、在 AndroidManifest.xml 注册Service

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

4、创建服务MyMqttService

package com.example.mqtttest01;import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;public class MyMqttService extends Service {public final String TAG = MyMqttService.class.getSimpleName();private static MqttAndroidClient  mqttAndroidClient;private        MqttConnectOptions mMqttConnectOptions;public        String HOST           = "tcp://111.35.5.201:61613";public        String USERNAME       = "admin";//用户名public        String PASSWORD       = "password";//密码public static String PUBLISH_TOPIC  = "tourist_enter";//发布主题public static String RESPONSE_TOPIC = "message_arrived";//响应主题// Build.getSerial() 的调用获取需要调用方拥有PHONE权限//public        String CLIENTID       = Build.getSerial();//客户端ID,一般以客户端唯一标识符表示,这里用设备序列号表示public        String CLIENTID       = "123456";@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {initMqtt();return super.onStartCommand(intent, flags, startId);}@Overridepublic IBinder onBind(Intent intent) {return null;}/*** 开启服务*/public static void startService(Context mContext) {mContext.startService(new Intent(mContext, MyMqttService.class));}/*** 发布 (模拟其他客户端发布消息)** @param message 消息*/public static void publish(String message) {String topic = PUBLISH_TOPIC;Integer qos = 2;Boolean retained = false;try {//参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息mqttAndroidClient.publish(topic, message.getBytes(), qos.intValue(), retained.booleanValue());} catch (MqttException e) {e.printStackTrace();}}/*** 响应 (收到其他客户端的消息后,响应给对方告知消息已到达或者消息有问题等)** @param message 消息*/public void response(String message) {String topic = RESPONSE_TOPIC;try {//参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息mqttAndroidClient.publish(topic, message.getBytes(), 2, false);} catch (MqttException e) {e.printStackTrace();}}/*** 初始化MQTT*/private void initMqtt() {String serverURI = HOST; //服务器地址(协议+地址+端口号)mqttAndroidClient = new MqttAndroidClient(this, serverURI, CLIENTID);mqttAndroidClient.setCallback(mqttCallback); //设置监听订阅消息的回调mMqttConnectOptions = new MqttConnectOptions();mMqttConnectOptions.setCleanSession(true); //设置是否清除缓存mMqttConnectOptions.setConnectionTimeout(30); //设置超时时间,单位:秒mMqttConnectOptions.setKeepAliveInterval(60); //设置心跳包发送间隔,单位:秒mMqttConnectOptions.setUserName(USERNAME); //设置用户名mMqttConnectOptions.setPassword(PASSWORD.toCharArray()); //设置密码// last will messageboolean doConnect = true;
//        String message = "{\"terminal_uid\":\"" + CLIENTID + "\"}";
//        String topic = PUBLISH_TOPIC;
//        Integer qos = 0;
//        Boolean retained = false;
//        if ((!message.equals("")) || (!topic.equals(""))) {
//            // 最后的遗嘱
//            try {
//                mMqttConnectOptions.setWill(topic, message.getBytes(), qos.intValue(), retained.booleanValue());
//            } catch (Exception e) {
//                Log.i(TAG, "Exception Occured", e);
//                doConnect = false;
//                iMqttActionListener.onFailure(null, e);
//            }
//        }if (doConnect) {doClientConnection();}}/*** 连接MQTT服务器*/private void doClientConnection() {if (!mqttAndroidClient.isConnected() && isConnectIsNomarl()) {try {mqttAndroidClient.connect(mMqttConnectOptions, null, iMqttActionListener);} catch (MqttException e) {e.printStackTrace();}}}/*** 判断网络是否连接*/private boolean isConnectIsNomarl() {ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo info = connectivityManager.getActiveNetworkInfo();if (info != null && info.isAvailable()) {String name = info.getTypeName();Log.i(TAG, "当前网络名称:" + name);return true;} else {Log.i(TAG, "没有可用网络");/*没有可用网络的时候,延迟3秒再尝试重连*/new Handler().postDelayed(new Runnable() {@Overridepublic void run() {doClientConnection();}}, 3000);return false;}}//MQTT是否连接成功的监听private IMqttActionListener iMqttActionListener = new IMqttActionListener() {@Overridepublic void onSuccess(IMqttToken arg0) {Log.i(TAG, "连接成功 ");try {mqttAndroidClient.subscribe(PUBLISH_TOPIC, 0);//订阅主题,参数:主题、服务质量} catch (MqttException e) {e.printStackTrace();}}@Overridepublic void onFailure(IMqttToken arg0, Throwable arg1) {arg1.printStackTrace();Log.i(TAG, "连接失败 ");doClientConnection();//连接失败,重连(可关闭服务器进行模拟)}};//订阅主题的回调private MqttCallback mqttCallback = new MqttCallback() {@Overridepublic void messageArrived(String topic, MqttMessage message) throws Exception {Log.i(TAG, "收到消息: " + new String(message.getPayload()));//收到消息,这里弹出Toast表示。如果需要更新UI,可以使用广播或者EventBus进行发送Toast.makeText(getApplicationContext(), "messageArrived: " + new String(message.getPayload()), Toast.LENGTH_LONG).show();//收到其他客户端的消息后,响应给对方告知消息已到达或者消息有问题等response("message arrived");}@Overridepublic void deliveryComplete(IMqttDeliveryToken arg0) {}@Overridepublic void connectionLost(Throwable arg0) {Log.i(TAG, "连接断开 ");doClientConnection();//连接断开,重连}};@Overridepublic void onDestroy() {try {mqttAndroidClient.disconnect(); //断开连接} catch (MqttException e) {e.printStackTrace();}super.onDestroy();}
}

5、开启服务

package com.example.mqtttest01;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MyMqttService.startService(this);//开启服务}
}

Android MQTT协议相关推荐

  1. Android Mqtt协议(连接、发布、订阅)实例、亲测可用

    实现步骤: 1.项目根目录build.gradle中添加: allprojects {repositories {...maven{ url "https://repo.eclipse.or ...

  2. 物联网阿里云——Android Mqtt协议连接阿里云

    实现步骤: 一.云平台端 1.首先在阿里云物联网平台创建产品和设备,获取设备三元组 {       "ProductKey": "a1QRE182gGH",   ...

  3. android mqtt详解_安卓开发之mqtt协议

    首先物联网协议mqtt协议是基于tcp/ip协议的,使用了官方的mqttclient框架 /* *初始化mqttclient */ private void init() { try { //MQTT ...

  4. mqtt android简书,iOS MQTT协议笔记

    前言 接到任务项目需要用MQTT来写消息推送,经过一段时间在网上查看资料后写下这篇文章,文章内容大都来自互联网,在文章最后也会贴出相关网址和Demo.写这文章主要目的是自己总结下经验做下笔记,以便日后 ...

  5. 一文读懂物联网 MQTT 协议之基础特性篇

    一.前言 上个月有个读者问我物联网 MQTT 协议实战相关的问题,我说后面会搞,没想到不知不觉一个月了,太忙了,再怎么忙答应的事情还是要给读者一个交代,所以就有了此文. 二.MQTT 协议概要 2.1 ...

  6. 一文读懂MQTT协议

    1  概述 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级 ...

  7. mqtt协议视频教程_MQTT协议教程

    mqtt协议视频教程 MQTT协议是一种广泛用于物联网的机器对机器(M2M)协议. 这是基于消息的协议. 它非常轻巧,因此在物联网生态系统中被采用. 几乎所有的 物联网云平台都支持MQTT协议,以从智 ...

  8. MQTT协议通俗讲解

    参考 Reference v3.1.1 英文原版 中文翻译版 其他资源 网站 MQTT官方主页 Eclipse Paho 项目主页 测试工具 MQTT Spy(基于JDK) Chrome插件 MQTT ...

  9. mqtt协议详解_IoT物联网设备上云技术方案详解

    随着传感器和通信技术的不断发展,物联网行业方兴未艾,业务链路涉及数据采集,通信连接,数据存储,数据可视化,洞察,行动决策.但,在实施过程中,碎片化的设备端通信连接难题往往就阻碍了项目落地进程. 今天, ...

最新文章

  1. 【ACM】杭电OJ 1005
  2. Java 程序员必须掌握的 10 款开源工具!
  3. 职工工资信息系统 c语言题,谁能帮我解决关于C语言的一些题?
  4. 王茂霖:数据挖掘提分三板斧!(附PPT下载)
  5. 零基础学编程学java还是python-学编程选Python还是Java?就业发展哪个好?
  6. eclipse如何使用log4j详解,你get了吗???
  7. BZOJ3534:[SDOI2014]重建(矩阵树定理)
  8. jQuery hash 插件
  9. java如何实现广告弹窗,WPF实现消息提醒(广告弹窗)
  10. CentOS 6系统启动流程细微解读,不可忽略引导扇区的1.5阶段。
  11. AspxTreeList获取选中项的值
  12. 谈谈你了解的python_你也可以侃侃而谈,一文带你了解Python的前世今生
  13. MS SQL Server和Oracle对数据库事务处理的差异性
  14. Ubuntu 系统调整LVM卷/home分区到 / 分区
  15. ArcGIS紧凑型切片读取与应用2-webgis动态加载紧凑型切片(附源码)
  16. 华为手机6130失效_华为手机的拨号键这5个功能,用过的人都拍手叫好,绝不虚吹...
  17. UE4 实现C++蓝图接口
  18. java 订单支付宝_Java支付宝订单查询
  19. 凯利讯讲解为什么MOS管可以防止电源反接?
  20. 热烈庆祝女朋友的生日

热门文章

  1. 个人日记-电影《心灵奇旅》观后感-20210118
  2. excel 两组数据交点_适用于安卓,苹果手机的Excel程序
  3. 在CentOS 5里使用 vault.centos.org 作为yum源
  4. 2019年经开区第四届青少年信息学竞赛小学组试题
  5. WIN7/XP双主分区独立双系统的引导教程
  6. matlab lognpdf用法,求助大神
  7. 2023 K8s 认证工程师 CKA 考题分析和题库练习(上)
  8. 《新lrc播放器2》-iPhone上可以显示lrc歌词的播放器可以在播放mp3文件时显示lrc文件中的歌词的播放器
  9. ADSL无法保存密码
  10. pandas—groupby如何得到分组里的数据