【Android】MQTT入门——服务器部署与客户端搭建

news2024/12/25 1:05:50

目录

  • MQTT 协议
    • 简介
    • 应用场景
    • 优点
    • 缺点
  • 部署服务端
    • 下载安装包
    • 启动服务器
  • 搭建客户端
    • 下载SDK
    • 添加依赖
    • 配置MQTT服务和权限
    • 建立连接
    • 订阅主题
    • 发布消息
    • 取消订阅
    • 断开连接
  • MQTT客户端工具
  • 最终效果
  • 实现传感器数据采集与监测功能思路

MQTT 协议

简介

MQTT(Message Queuing Telemetry Transport)是一种基于发布/订阅模式的轻量级消息传输协议,专门针对低带宽、和不稳定网络环境的物联网应用而设计,它可以用极少的代码为互联网设备提供实时可靠的消息服务。

应用场景

MQTT 协议主要用于物联网和移动设备等资源有限的场景中,其中包括物联网、移动互联网、智能硬件、车联网、智慧城市、远程医疗、电力、石油与能源等领域。案例例如:智能家居设备的控制与监控、传感器数据采集与监测、安防监控系统等。

优点

  • 是一种低带宽占用的即时通讯协议,在低带宽和不稳定的网络环境中也能较好地工作。
  • 针对低带宽网络,低计算能力的设备,做了特殊的优化,使得其能适应各种物联网应用场景。
  • 简单轻量,相比于其他传输协议,其代码占用内存少,对硬件要求低,适用于受限环境和低带宽网络。
  • 通过发布-订阅架构,实现了实时可靠的消息服务,并且具有 QoS 服务质量,能够保证消息的可靠传输。

QoS:是MQTT中消息传输的可靠性等级,由低到高分别是:

  • QoS0:最多一次。消息尽力发送一次,但不保证一定会被接收。
  • QoS1:至少一次。消息至少发送一次,但可能会被接收多次。
  • QoS2:有且仅有一次。消息只发送一次,且只会被接收一次

缺点

  • 不提供扩展性的支持,需要使用其他技术来实现分布式消息传递和扩展性。
  • 没有提供加密和身份验证机制。如果需要安全通信,则需要使用TLS/SSL等其他协议。
  • MQTT是一种轻量级的协议,但在高并发和大规模消息传递的环境中,可能会面临性能瓶颈。此外,在使用较高的QoS级别时,可能会导致更多的网络流量和延迟,从而影响系统的性能。

分布式:是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理,可以提供高性能、高可用性和弹性的计算和数据处理能力,满足不同规模和复杂度的应用需求。
TLS/SSL:详情请看文章👉 SSL/TLS 整理

部署服务端

话说在前,本文使用的是 EMQ 集成好的 MQTT 协议,使用起来相当简单,由于我的服务器即将到期,又没有续费的打算,我这里是在我的电脑上部署,如果你只是想着体验体验 MQTT ,跟着搞,准没错。

下载安装包

MQTT 支持部署在 Docker、Debian、Ubuntu、CentOS/RHEL、macOS、Kubernetes、Windows以及源码编译安装,小编电脑使用的是 Windows 系统,使用 Windows 下载 方式👉 前往下载所有版本的EMQX

如果没有服务器,你可以考虑部署在你的自用电脑上。

启动服务器

Windows 版本的 EMQX 下载完成后,解压文件,打开解压后的 bin 目录,使用 CMD 命令启动 EMQX。

# 解压后的 emqx 文件位于 D:\Softwares\emqx-5.2.0-windows-amd64\bin 目录下,因此使用 CMD 命令如下
D:\Softwares\emqx-5.2.0-windows-amd64\bin>emqx start

PS:EMQX 是部署在自用电脑上,当电脑重启时,需要重新启动 EMQX 服务。

完成这一步,打开浏览器,在地址栏输入 http:// 服务器IP :18083/ ,能打开服务器网页即完成部署。

在这里插入图片描述

搭建客户端

下载SDK

客户端,小编使用 Android 的Kotlin进行开发,MQTT 客户端 SDK 截止目前,已支持除 Android 外的 16 种 SDK,可根据自身需求不同,选择适合自身需求的开发包 👉 MQTT SDKs 下载
在这里插入图片描述

添加依赖

打开项目的 build.gradle 文件,添加 Eclipse Paho Java Client 和 Eclipse Paho Android Service 依赖到 dependencies ,并 Sync Now

dependencies {
    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.4'
    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1' 
}

配置MQTT服务和权限

打开项目的 AndroidManifest.xml 文件,加入以下配置。

<manifest>
	<uses-permission android:name="android.permission.INTERNET" />
	<!--  指示应用程序需要让设备保持开启状态的机制,通常配合 WakeLock 一起使用  -->
	<uses-permission android:name="android.permission.WAKE_LOCK" />
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

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

建立连接

// 如果你使用的也是自用电脑搭建的 MQTT 服务器,则需要想办法使移动设备、物联网设备与服务器处于同一网段下(例如:自用电脑和设备连接同一个WiFi),否则无法连接上
val serverURI = "tcp://服务器IP:1883"
val username = "服务器账号"
val password = "服务器密码"
private lateinit var mqttClient: MqttAndroidClient

fun connect(context: Context) {
	mqttClient = MqttAndroidClient(context, serverURI, "kotlin_client")
	mqttClient.setCallback(object : MqttCallback {
	    override fun messageArrived(topic: String?, message: MqttMessage?) {
	        Log.d(TAG, "Receive message: ${message.toString()} from topic: $topic")
	    }
	
	    override fun connectionLost(cause: Throwable?) {
	        Log.d(TAG, "Connection lost ${cause.toString()}")
	    }
	
	    override fun deliveryComplete(token: IMqttDeliveryToken?) {
	
	    }
	})
	val options = MqttConnectOptions()
	options.userName = username
	options.password = password.toCharArray()
	
    mqttClient.connect(options, null, object : IMqttActionListener {
	    override fun onSuccess(asyncActionToken: IMqttToken?) {
	        Log.d(TAG, "Connection success")
	    }
	
	    override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
	        Log.d(TAG, "Connection failure")
	    }
	})
}

订阅主题

mqttClient.subscribe(topic, qos, null, object : IMqttActionListener {
    override fun onSuccess(asyncActionToken: IMqttToken?) {
        Log.d(TAG, "Subscribed to $topic")
    }

    override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
        Log.d(TAG, "Failed to subscribe $topic")
    }
})

发布消息

mqttClient.publish(topic, message, null, object : IMqttActionListener {
    override fun onSuccess(asyncActionToken: IMqttToken?) {
        Log.d(TAG, "$msg published to $topic")
    }

    override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
        Log.d(TAG, "Failed to publish $msg to $topic")
    }
})

取消订阅

mqttClient.unsubscribe(topic, null, object : IMqttActionListener {
    override fun onSuccess(asyncActionToken: IMqttToken?) {
        Log.d(TAG, "Unsubscribed to $topic")
    }

    override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
        Log.d(TAG, "Failed to unsubscribe $topic")
    }
})

断开连接

mqttClient.disconnect(null, object : IMqttActionListener {
    override fun onSuccess(asyncActionToken: IMqttToken?) {
        Log.d(TAG, "Disconnected")
    }

    override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
        Log.d(TAG, "Failed to disconnect")
    }
})

MQTT客户端工具

至此,代码写完,我们可以使用 EMQ 提供的MQTT客户端工具和我们的应用进行测试。

点击下载 👉 MQTT 客户端工具

如果你只是抱着试一试的心态去了解MQTT,那么,你可以使用 EMQX MQTT Cloud 运营和维护的免费公共 MQTT 服务器, EMQX Cloud 是由 EMQ 推出的安全的 MQTT 物联网云服务平台,它提供一站式运维代管、独有隔离环境的 MQTT 5.0 接入服务。相关信息如下:

  • Broker:broker.emqx.io
  • TCP Port:1883
  • Websocket Port:8083

在这里插入图片描述

最终效果

同时使用 MQTTX 和 Android 客户端的最终效果如下所示:

在这里插入图片描述

实现传感器数据采集与监测功能思路

在文章开头我们有提到,MQTT 应用场景有包含 传感器数据采集与监测 一项,但经过我这段时间的研究,其实 MQTT 只是实现了设备消息的传递,并不能直接使用 MQTT 去对传感器数据进行采集与检测,实现传感器数据采集与监测这一功能,应该是传感器的事情,当传感器监测到设备数据有异常时,通过 MQTT 发送数据到服务端,再由服务端对接收到的异常数据进行处理。如图:
在这里插入图片描述

参考文献 & 资料来源

1、为什么智能硬件首选MQTT
2、MQTT 客户端库 & SDKs 下载
3、Android 使用 Kotlin 连接 MQTT
4、创建 MQTT 连接时如何设置参数?
5、MQTT 协议入门:基础知识和快速教程
6、物联网首选协议,关于 MQTT 你需要了解这些
7、MQTT在Android端的使用详解以及MQTT服务器搭建、Paho客户端使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1147715.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

剑指JUC原理-6.wait notify

wait nofity 小故事 - 为什么需要 wait 由于条件不满足&#xff0c;小南不能继续进行计算 但小南如果一直占用着锁&#xff0c;其它人就得一直阻塞&#xff0c;效率太低 于是老王单开了一间休息室&#xff08;调用 wait 方法&#xff09;&#xff0c;让小南到休息室&#xf…

C++可视化 有穷自动机NFA 有穷自动机DFA

一、项目介绍 根据正则表达式,可视化显示NFA&#xff0c;DFA&#xff1b;词法分析程序 二、项目展示

洛谷 B2007 A+B问题 C++代码

目录 题目描述 AC Code 题目描述 AC Code #include<bits/stdc.h> using namespace std; typedef long long ll; int main() { int a,b;cin>>a>>b;cout<<ab<<endl;return 0; }

F5修复了允许远程代码执行攻击的BIG-IP认证绕过漏洞

图片 导语 近日&#xff0c;网络安全公司Praetorian Security的研究人员发现了一项影响F5 BIG-IP配置工具的严重漏洞&#xff0c;该漏洞被命名为CVE-2023-46747。攻击者可以通过远程访问配置工具来执行未经身份验证的远程代码&#xff0c;从而对系统进行攻击。本文将详细介绍该…

基于 Python 的个性化电影推荐系统的研究与实现

1 简介 本毕业设计的内容是设计并且实现一个电影个性化推荐系统。它是在Windows下&#xff0c;以MYSQL为数据库开发平台&#xff0c;Python技术和Tomcat网络信息服务作为应用服务器。电影个性化推荐系统的功能已基本实现&#xff0c;主要实现首页&#xff0c;个人中心&#xf…

热力学第三定律

热力学第三定律能斯特定理 凝聚系的熵在等温过程中的改变随绝对温度趋于零 如果有 即有&#xff1a; 也就是说&#xff1a;当绝对温度趋于零时&#xff0c;熵和状态参量y无关。 普朗克绝对熵 当绝对温度趋于零时&#xff0c;一个化学均匀系统的熵趋向于一个极限值 也就是说&a…

【数据结构】面试OJ题——时间复杂度2

目录 一&#xff1a;移除元素 思路&#xff1a; 二&#xff1a;删除有序数组中的重复项 思路&#xff1a; 三&#xff1a;合并两个有序数组 思路1&#xff1a; 什么&#xff1f;你不知道qsort&#xff08;&#xff09; 思路2&#xff1a; 一&#xff1a;移除元素 27. 移…

离线语音通断器开发-稳定之后顺应新需求

使用云知声的US516p6方案开发了一系列的离线语音通断器&#xff0c;目前已经取得了不小的收获&#xff0c;有1路的&#xff0c;3路的&#xff0c;4路的&#xff0c;唛头和扬声器包括唛头线材也在不断的更新打磨中找到了效果特别好的供应商。 离线语音通断器&#xff0c;家用控…

【OpenCV实现平滑图像金字塔,轮廓:入门】

文章目录 概要图像金字塔轮廓&#xff1a;入门 概要 文章内容的概要&#xff1a; 平滑图像金字塔&#xff1a; 图像金字塔是什么&#xff1f; 图像金字塔是指将原始图像按照不同的分辨率进行多次缩小&#xff08;下采样&#xff09;得到的一系列图像。这种处理方式常用于图像…

openpnp - Warning - Unknown firmware

文章目录 openpnp - Warning - Unknown firmware概述笔记https://github.com/openpnp/openpnp/wiki/Motion-Controller-Firmwares备注END openpnp - Warning - Unknown firmware 概述 接上飞达控制板后, 显示未知固件的警告 开始没看源码之前, 总以为是回答的版本号不合适, …

L2-1 插松枝

L2-1 插松枝 分数 25 全屏浏览题目 切换布局 作者 陈越 单位 浙江大学 人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上&#xff0c;做成大大小小的松枝。他们的工作流程&#xff08;并不&#xff09;是这样的&#xff1a; 每人手边有一只小盒子&#xff0c;初始…

【算法-数组2】有序数组的平方 和 长度最小的子数组

今天&#xff0c;带来数组相关算法的讲解。文中不足错漏之处望请斧正&#xff01; 理论基础点这里 有序数组的平方 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输…

多线程---阻塞队列+生产者消费者模型

文章目录 阻塞队列自己实现一个阻塞队列&#xff08;三步&#xff09;标准库中的阻塞队列使用阻塞队列的优势 生产者消费者模型 阻塞队列 队列&#xff08;Queue&#xff09;是我们熟悉的一个数据结构&#xff0c;它是“先进先出”的。但是并不是所有的队列都是“先进先出”的…

椭圆曲线在SM2加解密中的应用(三)

一、SM2加密运算 1.1加密原始数据 SM2加密运算首先是用户A对数据加密,用户A拥有原始数据 椭圆曲线系统参数长度为klen比特的消息M公钥Pb椭圆曲线系统参数,已经在 椭圆曲线参数(二)中详细介绍;M就是需要加密消息,长度为klen; 1.1.1 公钥Pb的计算方式 公钥Pb=dBG,其中…

【MySQL--->复合查询】

文章目录 [TOC](文章目录) 一、基本查询二、多表查询三、自连接四、子查询1. 单行子查询2. 多行查询3.多列子查询4.在from语句中使用子查询5.合并查询 一、基本查询 查询工资高于500或岗位为MANAGER的雇员&#xff0c;同时还要满足他们的姓名首字母为大写的J 按照部门号升序而…

C++进阶篇3---二叉搜索树(Binary Search Tree)

一、二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的…

java之输入与输出的详细介绍

文章目录 输出的相关格式使用 Scanner 类进行控制台输入步骤&#xff1a;示例&#xff1a; 如何格式化输出&#xff1f;1. 使用 System.out.printf2. 使用 String.format printf与println 的区别printfprintln主要区别&#xff1a; 输出的相关格式 控制台输入是指通过命令行或…

JAVA中的垃圾回收器(2)------G1

一)G1垃圾回收器:-XX:UseG1GC:使用G1收集器 1)垃圾收集器迭代停顿时间越少越好&#xff0c;但是垃圾回收的总时间会增多&#xff0c;默认暂停时间默认是200ms&#xff0c;G1的内部底层算法非常复杂比CMS复杂&#xff0c;如果大内存&#xff0c;G1还比较有效果&#xff0c;但是如…

leetcode-数组

1.二分法手撕704&#xff08;诀窍在于用合法区间判断&#xff09;230810 左闭右闭: while(left<right)合法&#xff0c;middle(leftright)/2, if(nums[middle]>target)说明nums[middle]一定不是我们搜索的值&#xff0c;所以rightmiddle-1; elseif(nums[middle]<targe…