🏝️ 博主介绍
大家好,我是 一个搬砖的农民工,很高兴认识大家 😊 ~
👨🎓 个人介绍:本人是一名后端Java开发工程师,坐标北京 ~
🎉 感谢关注 📖 一起学习 📝 一起讨论 🌈 一起进步 ~
🙏 作者水平有限,欢迎各位大佬指正留言,相互学习进步 ~
首先推荐一家国内在MQTT做的非常不错的公司,我们常用的EMQX 和 MQTTX都是这家公司的开源产品,并且官网提供了MQTT相关文档,很适合初学者
⚡ 推荐参考:MQTT 快速开始
⚡ 推荐参考:MQTT 从入门到精通
1. MQTT介绍 🚀
🌈 1.1 简介
MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎,能够实现传感器、执行器和其它设备之间的高效通信。它凭借简单易实现、支持 QoS、报文小等特点,占据了物联网协议的半壁江山。
🍄 MQTT 主要组件 |
- ⭐ 客户端:是使用MQTT协议通信的设备或应用程序。客户端可以发布消息或订阅主题,以便接收其他客户端发布的消息。
- ⭐ 代理服务器(broker):,是负责消息路由和交换的中介软件。代理通过将客户端发送的消息路由到适当的目标客户端,实现了消息传递功能。
- ⭐ 主题:也称为 “topic”,是一种规范化的消息分类标识符。客户端可以订阅主题来接收特定类型的消息,也可以发布消息到特定的主题中。
这三个组件之间存在紧密联系。客户端可以向代理服务器订阅一个或多个主题,以便接收特定主题发布的消息。客户端还可以向代理服务器发布消息,该服务器将消息转发到已订阅主题的所有客户端。代理服务器负责将客户端之间的消息路由,并将消息投递到订阅该主题的所有客户端。通过这种方式,MQTT协议提供了一种轻量级,高效的消息传递机制,可以应用于各种IoT场景中,例如数据采集,传感器网络,可穿戴设备等。
🌈 1.2 常用MQTT 服务器
- Mosquitto: Mosquitto 是一个开源的 MQTT 代理服务器,支持安全连接和 QoS 2级别消息传递。它适用于低功耗设备和嵌入式环境。
- EMQX: EMQ X 是一款高可靠性、高可扩展性和高性能的 MQTT 代理服务器,支持数百万连接和百万级的消息传递。
- HiveMQ:HiveMQ 是一个 MQTT 代理服务器,同时支持 MQTT 3.1 和 MQTT 5.0协议,支持高可用性和水平扩展。
- ActiveMQ:ActiveMQ 是一款支持 MQTT 协议的消息代理服务器,可与其他 Apache 项目无缝集成,支持 Paho 和Eclipse Mosquitto 等 MQTT 客户端。
- IBM Watson IoT:IBM Watson IoT 是 IBM 公司提供的 IoT 平台,其 MQTT 客户端支持 MQTT 3.1 和 MQTT 5.0 协议,提供安全的设备到云端连接
🌈 1.3 常用MQTT 客户端库
- Paho MQTT 客户端:Paho Java 客户端是 Eclipse Paho 工程的一部分,提供了 Java 编写的 MQTT客户端库。它是兼容 MQTT 3.1 和 MQTT 3.1.1,适合在 Java 应用程序和 Android平台上使用。它提供了高质量的 MQTT 实现,支持多种通信协议和 API。
- Eclipse Mosquitto MQTT 客户端:Eclipse Mosquitto 是 Eclipse 基金会的一个子项目,提供MQTT 协议相关的工具和库。Mosquitto MQTT 客户端提供了各种语言的库,包括 Java,可以在 Spring Boot和其他 Java 应用程序中使用。
- HiveMQ MQTT 客户端:HiveMQ 是 MQTT 官方规范中使用的 MQTT broker之一,它提供了高度扩展和高可用性的解决方案。HiveMQ 客户端提供了多种编程语言的 API,包括 Java,可以与 Spring Boot 应用程序集成。
🌈 1.4 常用MQTT 客户端工具
- MQTT.fx:一个跨平台的MQTT客户端工具,支持订阅和发布主题,可以显示消息、报警,并支持加密和ACL等功能。
- MQTT Explorer:可以在Windows、Linux和macOS上运行,支持订阅和发布主题,支持展示消息历史记录,并提供连接参数的配置功能。
- MQTT X:一个基于Electron框架的MQTT客户端工具,可以在Windows、macOS和Linux上运行,除了支持订阅和发布主题外,还支持与AWS IoT Hub、Microsoft Azure IoT Hub和Google Cloud IoT Core建立连接。
- HiveMQ:由HiveMQ公司提供的MQTT客户端测试工具,支持压力测试和性能分析,可以用于测试MQTT服务器的稳定性和可扩展性。
- Eclipse Mosquitto:Eclipse基金会维护的一个MQTT代理服务器和MQTT客户端库,可以用于搭建MQTT服务器和开发MQTT客户端程序。
- MQTTool:一个可扩展、跨平台的MQTT客户端工具,支持订阅和发布主题、调试MQTT消息和转换消息格式等功能。
其中,MQTT.fx、MQTT Explorer和MQTT X这三个工具比较流行和好用,可以根据自己的操作系统和使用需求选择适合自己的工具。
🌈 1.5 MQTT 客户端库 和 MQTT 客户端工具 的区别
以 paho、mqttx、mqttfx 来举例:
- ⭐ Paho是一个Java语言的MQTT客户端库,它提供了MQTT订阅和发布消息的API,主要用于开发Java语言的应用程序,如Android应用程序等。
- ⭐ MQTTfx和MQTTX则是MQTT客户端工具,它们提供了UI界面,比如订阅和发布消息的界面、主题订阅列表界面、插件等。MQTTfx是使用JavaFX编写的跨平台应用程序,MQTTX是使用Electron框架编写的跨平台应用程序,它们的主要目的是方便用户直接操作MQTT协议,以便进行测试、调试或监控。
因此,Paho是一个MQTT客户端库,主要提供API用于在Java应用程序中实现MQTT客户端
,而MQTTfx和MQTTX是两个MQTT客户端工具,主要提供GUI界面帮助用户配置MQTT客户端,通过MQTT协议实现消息订阅和发布等操作
。它们的目的和用途不同,但都是为了更方便、更高效地使用MQTT协议。
2. MQTT协议 🚀
🌈 2.1 消息主题 Topic
MQTT 主题本质上是一个 UTF-8 编码的字符串,是 MQTT 协议进行消息路由的基础。MQTT 主题类似 URL 路径
🌈 2.2 消息质量服务 QoS
MQTT 定义了三种不同 QoS 等级的 消息质量服务
🌈 2.3 保留消息 retain
主题发布保留消息后,订阅该主题能获取该主题最新一条
保留消息
MQTT 保留消息是什么?如何使用?
🌈 2.4 清空会话标志 Clean Session
🌈 2.5 遗嘱消息 Necklace
3. MQTT应用 🚀
🌈 3.1 使用MQTT客户端工具订阅和发布
1、EMQX开源版下载地址:www.emqx.com/zh/try?prod…
2、windows版本下载完后在bin目录下运行:
emqx start
启动mqtt服务器
3、启动成功后访问:http://127.0.0.1:18083/#/
4、MQTTX下载地址:www.emqx.com/zh/try?prod…
5、打开MQTTX客户端,配置要连接的MQTT服务端
6、即可对这个服务端订阅和发布
7、MQTT.fx使用和MQTTX类似
🌈 3.2 java中集成MQTT客户端库
1、引入maven依赖
使用比较常用的 Eclipse Paho Java Client作为客户端,该客户端是 Java 语言中使用最为广泛的 MQTT 客户端库。
<dependencies>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>
2、发布者 代码类
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
/**
* @Filename: Test
* @Author: sheng.wanping
* <li>Date: 2023/6/5 11:13</li>
* <li>Version: 1.0</li>
* <li>Content: create</li>
*/
public class Test {
public static void main(String[] args) {
String broker = "tcp://localhost:1883";
String topic = "testtopic/test";
String username = "emqx";
String password = "public";
String clientid = "publish_client";
String content = "Hello MQTT";
int qos = 0;
try {
MqttClient client = new MqttClient(broker, clientid, new MemoryPersistence());
// 连接参数
MqttConnectOptions options = new MqttConnectOptions();
// 设置用户名和密码
// options.setUserName(username);
// options.setPassword(password.toCharArray());
// options.setConnectionTimeout(60); // 连接超时,默认30
// options.setKeepAliveInterval(60); // 心跳,默认60
// 连接
client.connect(options);
// 创建消息并设置 QoS
MqttMessage message = new MqttMessage(content.getBytes());
message.setQos(qos);
// 发布消息
client.publish(topic, message);
System.out.println("Message published");
System.out.println("topic: " + topic);
System.out.println("message content: " + content);
// 关闭连接
client.disconnect();
// 关闭客户端
} catch (MqttException e) {
throw new RuntimeException(e);
}
}
}
3、订阅者 代码类
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public class SubscribeSample {
public static void main(String[] args) {
String broker = "tcp://localhost:1883";
String topic = "testtopic/test";
String username = "emqx";
String password = "public";
String clientid = "subscribe_client";
int qos = 0;
try {
MqttClient client = new MqttClient(broker, clientid, new MemoryPersistence());
// 连接参数
MqttConnectOptions options = new MqttConnectOptions();
// options.setUserName(username);
// options.setPassword(password.toCharArray());
// options.setConnectionTimeout(60);
// options.setKeepAliveInterval(60);
// 设置回调
client.setCallback(new MqttCallback() {
public void connectionLost(Throwable cause) {
System.out.println("connectionLost: " + cause.getMessage());
}
public void messageArrived(String topic, MqttMessage message) {
System.out.println("topic: " + topic);
System.out.println("Qos: " + message.getQos());
System.out.println("message content: " + new String(message.getPayload()));
}
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("deliveryComplete---------" + token.isComplete());
}
});
client.connect(options);
client.subscribe(topic, qos);
} catch (Exception e) {
e.printStackTrace();
}
}
}
🍄 MQTT的CONNECT报文 |
MQTT的CONNECT报文用于建立客户端与MQTT代理服务器之间的连接。CONNECT报文包含以下属性:
- 协议名称和版本号(Protocol Name, Protocol Version):指定MQTT协议的版本号,例如“MQTT 3.1.1”。
- 清理会话标志(Clean Session):指定是否清除客户端与代理服务器之间的会话状态。如果设置为1,代理服务器将删除客户端之前发布的所有主题和订阅信息;如果设置为0,则保留之前的会话状态。
- 保持连接时间(Keep Alive):指定客户端与代理服务器之间的最长空闲时间,超过此时间连接将被断开。
- 客户端标识符(Client Id):指定客户端的唯一标识符,用于在代理服务器上标识客户端。客户端标识符是必需的,且必须唯一。
- 遗嘱标志(Will Flag):指定是否发送遗嘱消息。如果设置为1,则代理服务器将在客户端离线时发布一条遗嘱消息。
- 遗嘱主题(Will Topic):指定遗嘱消息的主题。
- 遗嘱消息(Will Message):指定遗嘱消息的内容。
- 用户名和密码(User Name, Password):用于认证客户端的身份。如果需要认证,客户端可以提供用户名和密码。
🍄 MQTT主题通配符 |
⚡ 推荐参考: 通过案例理解 MQTT 主题与通配符
如果你不想在启动类中订阅MQTT服务器,你可以将订阅代码放在任何你希望订阅的地方,只要在应用程序启动后执行即可。
以下是一些可行的方式来订阅MQTT服务器:
在控制器中订阅:你可以在Spring Boot应用程序的控制器中添加一个API接口,当该接口被调用时执行订阅逻辑。例如,你可以创建一个订阅接口,并在其中执行订阅代码:
@RestController
public class SubscribeController {
@GetMapping("/subscribe")
public String subscribeToMqttServer() {
String topic = "your_topic";
MyMqttCallback callback = new MyMqttCallback();
MqttClientUtil.subscribe(topic, callback);
return "订阅成功";
}
}
这样,当访问"/subscribe"接口时,将执行订阅操作。
在定时任务中订阅:你可以使用Spring的定时任务来执行订阅操作。首先,你需要在应用程序中添加一个定时任务配置类。例如,创建一个SubscribeTask类并添加@Scheduled注解来定时执行任务:
@Component
public class SubscribeTask {
@Scheduled(fixedRate = 5000) // 每隔5秒执行
public void subscribeToMqttServer() {
String topic = "your_topic";
MyMqttCallback callback = new MyMqttCallback();
MqttClientUtil.subscribe(topic, callback);
}
}
这样,每隔5秒,定时任务将执行一次订阅操作。
注意:无论你选择哪种方式,确保在订阅之前MqttClientUtil类和MyMqttCallback类已经被正确注入并实例化,以便调用订阅方法。
🌈 3.3 MQTT工具类
⚡ 推荐参考:MQTT工具类