Android MQTT协议
1、关于MQTT简介
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议。它是一种发布/订阅,极其简单和轻量级的消息传递协议,专为受限设备和低带宽,高延迟或不可靠的网络而设计。它的设计思想是轻巧、开放、简单、规范,易于实现。这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器的通信(M2M)以及物联网环境。相对于XMPP,MQTT更加轻量级,并且占用的宽带低。
MQTT协议有以下特点:
- 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。
- 对负载内容屏蔽的消息传输。
- 使用 TCP/IP 提供网络连接。
- 有三种消息发布服务质量:
- qos为0:“至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
- qos为1:“至少一次”,确保消息到达,但消息重复可能会发生。这一级别可用于如下情况,你需要获得每一条消息,并且消息重复发送对你的使用场景无影响。
- qos为2:“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
- 小型传输,开销很小(固定长度的头部是 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协议相关推荐
- Android Mqtt协议(连接、发布、订阅)实例、亲测可用
实现步骤: 1.项目根目录build.gradle中添加: allprojects {repositories {...maven{ url "https://repo.eclipse.or ...
- 物联网阿里云——Android Mqtt协议连接阿里云
实现步骤: 一.云平台端 1.首先在阿里云物联网平台创建产品和设备,获取设备三元组 { "ProductKey": "a1QRE182gGH", ...
- android mqtt详解_安卓开发之mqtt协议
首先物联网协议mqtt协议是基于tcp/ip协议的,使用了官方的mqttclient框架 /* *初始化mqttclient */ private void init() { try { //MQTT ...
- mqtt android简书,iOS MQTT协议笔记
前言 接到任务项目需要用MQTT来写消息推送,经过一段时间在网上查看资料后写下这篇文章,文章内容大都来自互联网,在文章最后也会贴出相关网址和Demo.写这文章主要目的是自己总结下经验做下笔记,以便日后 ...
- 一文读懂物联网 MQTT 协议之基础特性篇
一.前言 上个月有个读者问我物联网 MQTT 协议实战相关的问题,我说后面会搞,没想到不知不觉一个月了,太忙了,再怎么忙答应的事情还是要给读者一个交代,所以就有了此文. 二.MQTT 协议概要 2.1 ...
- 一文读懂MQTT协议
1 概述 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级 ...
- mqtt协议视频教程_MQTT协议教程
mqtt协议视频教程 MQTT协议是一种广泛用于物联网的机器对机器(M2M)协议. 这是基于消息的协议. 它非常轻巧,因此在物联网生态系统中被采用. 几乎所有的 物联网云平台都支持MQTT协议,以从智 ...
- MQTT协议通俗讲解
参考 Reference v3.1.1 英文原版 中文翻译版 其他资源 网站 MQTT官方主页 Eclipse Paho 项目主页 测试工具 MQTT Spy(基于JDK) Chrome插件 MQTT ...
- mqtt协议详解_IoT物联网设备上云技术方案详解
随着传感器和通信技术的不断发展,物联网行业方兴未艾,业务链路涉及数据采集,通信连接,数据存储,数据可视化,洞察,行动决策.但,在实施过程中,碎片化的设备端通信连接难题往往就阻碍了项目落地进程. 今天, ...
最新文章
- 【ACM】杭电OJ 1005
- Java 程序员必须掌握的 10 款开源工具!
- 职工工资信息系统 c语言题,谁能帮我解决关于C语言的一些题?
- 王茂霖:数据挖掘提分三板斧!(附PPT下载)
- 零基础学编程学java还是python-学编程选Python还是Java?就业发展哪个好?
- eclipse如何使用log4j详解,你get了吗???
- BZOJ3534:[SDOI2014]重建(矩阵树定理)
- jQuery hash 插件
- java如何实现广告弹窗,WPF实现消息提醒(广告弹窗)
- CentOS 6系统启动流程细微解读,不可忽略引导扇区的1.5阶段。
- AspxTreeList获取选中项的值
- 谈谈你了解的python_你也可以侃侃而谈,一文带你了解Python的前世今生
- MS SQL Server和Oracle对数据库事务处理的差异性
- Ubuntu 系统调整LVM卷/home分区到 / 分区
- ArcGIS紧凑型切片读取与应用2-webgis动态加载紧凑型切片(附源码)
- 华为手机6130失效_华为手机的拨号键这5个功能,用过的人都拍手叫好,绝不虚吹...
- UE4 实现C++蓝图接口
- java 订单支付宝_Java支付宝订单查询
- 凯利讯讲解为什么MOS管可以防止电源反接?
- 热烈庆祝女朋友的生日
热门文章
- 个人日记-电影《心灵奇旅》观后感-20210118
- excel 两组数据交点_适用于安卓,苹果手机的Excel程序
- 在CentOS 5里使用 vault.centos.org 作为yum源
- 2019年经开区第四届青少年信息学竞赛小学组试题
- WIN7/XP双主分区独立双系统的引导教程
- matlab lognpdf用法,求助大神
- 2023 K8s 认证工程师 CKA 考题分析和题库练习(上)
- 《新lrc播放器2》-iPhone上可以显示lrc歌词的播放器可以在播放mp3文件时显示lrc文件中的歌词的播放器
- ADSL无法保存密码
- pandas—groupby如何得到分组里的数据