热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AndroidMQTT消息推送全面解析

什么是MQTT?MQTT(消息队列遥测传输)是ISO标准(ISOIECPRF20922)下基于发布订阅范式的消息协议。它工作在TCPIP协议族上,是为

什么是MQTT?

MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。

MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

 


发布订阅模式?

发布订阅模式区别于传统的客户端-服务器模式,它使发送消息的客户端(发布者)与接收消息的客户端(订阅者)分离,发布者与订阅者不需要建立直接联系。

我们既可以让多个发布者向一个订阅者发布消息,也可以让多个订阅者同时接收一个发布者的消息,它的精髓在于由一个被称为代理的中间角色负责所有消息路由和分发的工作。

传统的客户端-服务器模式可以实现类似的效果,但是无法做到像发布订阅模式这样简洁和优雅。

 

发布订阅模式的优点在于发布者与订阅者的解耦,这种解耦表现在以下两个方面:


  • 空间解耦,订阅者与发布者不需要建立直接连接,新的订阅者想要加入网络时不需要修改发布者的行为。
  • 时间解耦,订阅者和发布者不需要同时在线,即便不存在订阅者也不影响发布者发布消息。

直接上深海画的图吧:

 

怎么样画的可还行?

图中蓝紫色的框代表一个群组,该群组有三个客户端,群组所有成员均在服务器订阅了消息。

 当第一个客户端发布消息到服务器(中转站)的时候,他将推送消息给每一个订阅的客户端。

简洁一点分三步:


  1. 一批客户端→服务器     订阅
  2. 一个客户端→服务器     发布消息
  3. 服务器→一批客户端     推送消息

代码实现:

准备1:在你的根目录的build.gradle 的某括号里 加以下代码

repositories {maven {url "https://repo.eclipse.org/content/repositories/paho-releases/" //mqtt}}

准备2: 在你的.app目录下的 build.gradle 的某括号里 加以下代码     假如你的开发环境是AndroidX   那么不加最后一行会报异常:Landroidx/localbroadcastmanager/content/LocalBroadcastManager;

compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1' //mqttcompile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1' //mqttimplementation 'com.android.support:support-v4:4.4.1'//mqtt 爆红新加 如已有请忽略

准备3: 在你的AndroidManifest 中注册activity的地方注册两个Service     

 核心类:         

1.接收消息的地方我写了todo  找不到可以搜一下   

2.写host的时候前面记得写这个 tcp://

3.断开连接的遗嘱  我加了注释:找不到可以搜一下遗嘱   

假如你不知道遗嘱是啥  请继续往下看 深海给你讲

/*** Created by Xinghai.Zhao on 2021/3/17.*/public class MQTTService extends Service {public static final String TAG = MQTTService.class.getSimpleName();private static MqttAndroidClient client;private MqttConnectOptions conOpt;private String host = "tcp://你要连接的IP地址";private String userName = "xxx";private String passWord = "xxx";private static String myTopic = "xxx";//要订阅的主题 private String clientId = "xxx";@Overridepublic void onCreate() {super.onCreate();Log.e(getClass().getName(), "onCreate");init();}public static void publish(String msg){String topic = myTopic;Integer qos = 0;Boolean retained = false;try {if (client != null){client.publish(topic, msg.getBytes(), qos.intValue(), retained.booleanValue());}} catch (MqttException e) {e.printStackTrace();}}private void init() {// 服务器地址(协议+地址+端口号)String uri = host;client = new MqttAndroidClient(this, uri, clientId);// 设置MQTT监听并且接受消息client.setCallback(mqttCallback);cOnOpt= new MqttConnectOptions();// 断线重连conOpt.setAutomaticReconnect(true);// 清除缓存conOpt.setCleanSession(true);// 设置超时时间,单位:秒conOpt.setConnectionTimeout(10);// 心跳包发送间隔,单位:秒conOpt.setKeepAliveInterval(20);// 用户名conOpt.setUserName(userName);// 密码conOpt.setPassword(passWord.toCharArray()); //将字符串转换为字符串数组// last will messageboolean doCOnnect= true;String message = "";Log.e(getClass().getName(), "message是:" + message);String topic = myTopic;Integer qos = 0;Boolean retained = false;if ((!message.equals("")) || (!topic.equals(""))) {// 最后的遗嘱// MQTT本身就是为信号不稳定的网络设计的,所以难免一些客户端会无故的和Broker断开连接。//当客户端连接到Broker时,可以指定LWT,Broker会定期检测客户端是否有异常。//当客户端异常掉线时,Broker就往连接时指定的topic里推送当时指定的LWT消息。try {conOpt.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();}}@Overridepublic void onDestroy() {stopSelf();try {client.disconnect();} catch (MqttException e) {e.printStackTrace();}super.onDestroy();}/** 连接MQTT服务器 */private void doClientConnection() {if (!client.isConnected() && isConnectIsNormal()) {try {client.connect(conOpt, null, iMqttActionListener);} catch (MqttException e) {e.printStackTrace();}}}// MQTT是否连接成功private IMqttActionListener iMqttActiOnListener= new IMqttActionListener() {@Overridepublic void onSuccess(IMqttToken arg0) {Log.i(TAG, "连接成功 ");try {// 订阅myTopic话题client.subscribe(myTopic,1);} catch (MqttException e) {e.printStackTrace();}}@Overridepublic void onFailure(IMqttToken arg0, Throwable arg1) {arg1.printStackTrace();// 连接失败,重连}};// MQTT监听并且接受消息private MqttCallback mqttCallback = new MqttCallback() {@Overridepublic void messageArrived(String topic, MqttMessage message) throws Exception {String str1 = new String(message.getPayload());String str2 = topic + ";qos:" + message.getQos() + ";retained:" + message.isRetained();Log.i(TAG, "messageArrived:" + str1);Log.i(TAG, str2);// todo 接收到消息后进行后续处理}@Overridepublic void deliveryComplete(IMqttDeliveryToken arg0) {}@Overridepublic void connectionLost(Throwable arg0) {// 失去连接,重连}};/** 判断网络是否连接 */private boolean isConnectIsNormal() {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, "MQTT当前网络名称:" + name);return true;} else {Log.i(TAG, "MQTT 没有可用网络");return false;}}@Overridepublic IBinder onBind(Intent intent) {Log.e(getClass().getName(), "onBind");return new CustomBinder();}public class CustomBinder extends Binder {public MQTTService getService(){return MQTTService.this;}}}

遗嘱(掉线遗言)(意愿消息)

因为连接的时候提前告知了服务器断开后的处理信息,所以当服务器发现该客户断开连接的时候,会处理改信息。

某资料: (稍后我会将该资料传到资源中)

 

 

 

 

 


推荐阅读
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 解决.net项目中未注册“microsoft.ACE.oledb.12.0”提供程序的方法
    在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报错“未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序”。本文提供了解决这个问题的方法,包括错误描述和代码示例。通过注册提供程序和修改连接字符串,可以成功读取excel文件信息。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
author-avatar
益清613
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有