【Android】MQTT
目录
- 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客户端使用