在Spring Boot项目中集成和使用MQTT
在物联网(IoT)应用中,MQTT(消息队列遥测传输)协议因其轻量级和高效性被广泛使用。在Spring Boot项目中,我们可以通过集成org.springframework.integration:spring-integration-mqtt依赖来实现对MQTT的支持。本文将逐步介绍如何在Spring Boot应用中使用MQTT。
1. 添加依赖
首先,我们需要在项目的pom.xml文件中添加Spring Integration MQTT的依赖:
<dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- Spring Integration MQTT --><dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-mqtt</artifactId></dependency><!-- MQTT Client Library (Paho) --><dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse.paho.client.mqttv3</artifactId></dependency>
</dependencies>
2. 配置MQTT
在Spring Boot应用的配置文件application.properties中添加MQTT相关配置:
mqtt.broker.url=tcp://localhost:1883
mqtt.client.id=spring-boot-mqtt-client
mqtt.username=your-username
mqtt.password=your-password
mqtt.default.topic=your/topic
3. 创建MQTT配置类
创建一个新的配置类,用于配置MQTT连接和消息处理:
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;@Configuration
public class MqttConfig {@Beanpublic MqttPahoClientFactory mqttClientFactory() {DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();MqttConnectOptions options = new MqttConnectOptions();options.setServerURIs(new String[] { "tcp://localhost:1883" });options.setUserName("your-username");options.setPassword("your-password".toCharArray());factory.setConnectionOptions(options);return factory;}@Beanpublic MessageChannel mqttInputChannel() {return new DirectChannel();}@Beanpublic MessageProducer inbound() {MqttPahoMessageDrivenChannelAdapter adapter =new MqttPahoMessageDrivenChannelAdapter("spring-boot-mqtt-client-inbound",mqttClientFactory(), "your/topic");adapter.setCompletionTimeout(5000);adapter.setConverter(new DefaultPahoMessageConverter());adapter.setQos(1);adapter.setOutputChannel(mqttInputChannel());return adapter;}@Bean@ServiceActivator(inputChannel = "mqttInputChannel")public MessageHandler handler() {return message -> {String payload = (String) message.getPayload();System.out.println("Received message: " + payload);};}@Beanpublic MessageChannel mqttOutboundChannel() {return new DirectChannel();}@Bean@ServiceActivator(inputChannel = "mqttOutboundChannel")public MessageHandler mqttOutbound() {MqttPahoMessageHandler messageHandler =new MqttPahoMessageHandler("spring-boot-mqtt-client-outbound", mqttClientFactory());messageHandler.setAsync(true);messageHandler.setDefaultTopic("your/topic");return messageHandler;}
}
4. 发送和接收消息
在你的服务或控制器中,可以使用如下方法发送消息:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.MessageChannel;
import org.springframework.stereotype.Service;@Service
public class MqttMessageSender {@Autowiredprivate MessageChannel mqttOutboundChannel;public void sendMessage(String topic, String payload) {mqttOutboundChannel.send(MessageBuilder.withPayload(payload).setHeader("mqtt_topic", topic).build());}
}
要接收消息,可以配置handler方法中的处理逻辑,或将消息发送到另一个Spring Integration通道进行进一步处理。
5. 使用示例
在一个控制器中调用发送消息方法:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MqttController {@Autowiredprivate MqttMessageSender mqttMessageSender;@GetMapping("/send")public String send(@RequestParam String topic, @RequestParam String message) {mqttMessageSender.sendMessage(topic, message);return "Message sent to topic " + topic;}
}
这样,你就可以通过HTTP请求发送MQTT消息了。例如,访问http://localhost:8080/send?topic=test/topic&message=Hello,将消息发送到MQTT主题test/topic。
这就是一个完整的Spring Boot应用中集成MQTT的简单示例,希望对你有所帮助!
MQTT报文头介绍
MQTT协议的请求报文头非常轻量级。MQTT协议定义了固定报文头和可变报文头两部分。以下是各类报文的基本格式:
固定报文头
所有MQTT报文都有一个固定报文头,占据2-5个字节。固定报文头包含报文类型和一些控制标志。
固定报文头格式
-
第一个字节:
- 位7-4:报文类型(Message Type)
- 位3-0:标志(Flags),根据报文类型不同而不同
-
第二个字节及后续字节:
- 剩余长度(Remaining Length),表示剩余报文的字节数。采用可变长度编码,每个字节的最高位用于指示是否有后续字节。
各类报文示例
连接报文(CONNECT)
连接报文用于客户端请求与服务器建立连接。其报文头如下:
-
固定报文头:
- 第一个字节:0x10(CONNECT报文类型是1,标志位为0000)
- 第二个字节:剩余长度(根据可变部分长度而定)
-
可变报文头:
- 协议名(“MQTT”)
- 协议级别(4,表示MQTT 3.1.1)
- 连接标志(Connect Flags)
- 保持连接时间(Keep Alive)
-
有效载荷:
- 客户端标识符(Client Identifier)
- 用户名(可选)
- 密码(可选)
- 遗嘱主题(可选)
- 遗嘱消息(可选)
连接确认报文(CONNACK)
服务器响应客户端的连接请求。其报文头如下:
-
固定报文头:
- 第一个字节:0x20(CONNACK报文类型是2,标志位为0000)
- 第二个字节:剩余长度(2字节)
-
可变报文头:
- 连接确认标志(0x00或0x01)
- 返回码(0表示连接成功,其他值表示错误)
发布报文(PUBLISH)
客户端或服务器发送消息到指定主题。其报文头如下:
-
固定报文头:
- 第一个字节:0x30(PUBLISH报文类型是3,标志位根据QoS等级、重复标志和保留标志变化)
- 第二个字节:剩余长度(根据主题名、消息ID和消息体长度而定)
-
可变报文头:
- 主题名(Topic Name)
- 消息ID(QoS等级为1或2时需要)
-
有效载荷:
- 消息内容
示例
以下是一个PUBLISH报文的示例:
30 0B # 固定报文头 (PUBLISH,QoS 0)
00 05 # 主题名长度
74 6F 70 69 63 # 主题名 "topic"
68 65 6C 6C 6F # 消息内容 "hello"
在这个示例中:
- 第一个字节
0x30表示这是一个PUBLISH报文,QoS等级为0,重复标志和保留标志为0。 - 第二个字节
0x0B表示剩余长度为11个字节。 - 接下来的两个两个字节 0x00 0x05 表示主题名的长度为5个字节。
- 接下来的5个字节 0x74 0x6F 0x70 0x69 0x63 表示主题名 “topic”。
- 最后5个字节 0x68 0x65 0x6C 0x6C 0x6F 表示消息内容 “hello”。
这种结构使得MQTT报文非常紧凑和高效,特别适合物联网设备的通信。希望这篇文章能帮助你更好地理解和使用MQTT协议。
相关文章:
在Spring Boot项目中集成和使用MQTT
在物联网(IoT)应用中,MQTT(消息队列遥测传输)协议因其轻量级和高效性被广泛使用。在Spring Boot项目中,我们可以通过集成org.springframework.integration:spring-integration-mqtt依赖来实现对MQTT的支持。…...
14、设计模式之访问者模式
访问者模式 在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元…...
Excel如何换行不换格
在换行的字之间 按住Alt 回车...
Elasticsearch 8.1官网文档梳理 - 十五、Aggregations(聚合)
Aggregations ES 的聚合可以总结为三类:指标聚合、统计聚合、其他分析聚合。 Metric aggregations: 计算 field 的指标值,例如平均值、最大值、和等指标Bucket aggregations: 基于 field 的值、范围、或其他标准对 doc 分类&…...
计算机系统概论
目录 1. 计算机的分类 2. 计算机的发展简史 3. 计算机的硬件 1. 处理器(CPU) 2. 内存(Memory) 3. 存储设备 4. 输入输出设备 4. 计算机的软件 1. 软件的分类 1.1 系统软件 1.2 应用软件 2. 软件的特点 3. 软件开发 4…...
【Vue】diff 算法
diff的时机 当组件创建时,以及依赖的属性或数据变化时,会运行一个函数,该函数会做两件事: 运行_render生成一棵新的虚拟dom树(vnode tree),返回根节点运行_update,传入虚拟dom树的根节点,对新旧…...
Spring Boot 3.x 与 Spring Boot 2.x 的对比
Spring Boot 是 Java 开发领域的一个重要框架,它简化了基于 Spring 的应用开发。随着版本的不断更新,Spring Boot 提供了更多功能、更好的性能以及更简洁的配置。本文将详细对比 Spring Boot 3.x 和 Spring Boot 2.x,探讨它们之间的主要区别和…...
SSLError ClosedPoolError
分析日志 从您提供的日志文件内容来看,存在几个明显的问题导致了实例无法创建: SSL证书验证失败:日志中多次出现SSLError(SSLError(1, [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:897)),)错误。这表明客户端在尝试…...
勒索软件分析_Conti
0. Conti介绍 勒索软件即服务(Ransomware as a Service,RaaS)变体 Conti 推出还不到两年,已经进行了第七次迭代。Conti被证明是一种敏捷而熟练的恶意软件威胁,能够自主和引导操作,并具有无与伦比的加密速度…...
Linux系统如何通过编译方式安装python3.11.3
1.切换到/data 目录 cd /data 2.下载python源码Python-3.11.3.tgz wget https://www.python.org/ftp/python/3.11.3/Python-3.11.3.tgz tar -xzf Python-3.11.0.tgz cd Python-3.11.3 3.配置python的安装路径 和 执行openssl的路径 ./configure --prefix/usr/local/pyth…...
仿《Q极速体育》NBACBA体育直播吧足球直播综合体育直播源码
码名称:仿《Q极速体育》NBACBA体育直播吧足球直播综合体育直播源码 开发环境:帝国cms7.5 空间支持:phpmysql 仿《Q极速体育》NBACBA体育直播吧足球直播综合体育直播源码自动采集 - 我爱模板网源码名称:仿《Q极速体育》NBACBA体育直…...
代码随想录算法训练营第四天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点 、 面试题 02.07. 链表相交、142.环形链表II
24. 两两交换链表中的节点 题目链接: 24. 两两交换链表中的节点 文档讲解:代码随想录 状态:没做出来,没有正确更新头节点,因为head和cur共享引用,会随着cur的移动,丢失之前存放的节点 错误代码&…...
吉林大学计科21级《软件工程》期末考试真题
文章目录 21级期末考试题一、单选题(2分一个,十个题,一共20分)二、问答题(5分一个,六个题,一共30分)三、分析题(一个10分,一共2个,共20分…...
AWS云服务器每月费用高昂,如何优化达到节省目的?
AWS云服务器每月费用可能因不同的使用情况和配置而有所不同。为了优化并节省AWS云服务器的费用,aws的合作伙伴九河云提供了一些建议: (1)调整实例大小:确保你使用的实例大小与你的工作负载相匹配。实例的容量每增加一倍…...
关于XtremIO 全闪存储维护的一些坑(建议)
XtremIO 是EMC过去主推的一款全闪存储系统,号称性能小怪兽,对付那些对于性能要求极高的业务场景是比较合适的,先后推出了1代和2代产品,目前这个产品好像未来的演进到了PowerStor或者PowerMax全闪,应该不独立发展这个产…...
《最新出炉》系列入门篇-Python+Playwright自动化测试-41-录制视频
宏哥微信粉丝群:https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 1.简介 上一篇讲解和分享了录制自动生成脚本,索性连带录制视频也一股脑的在这里就讲解和分享了。今天我们将学习如何使用Playwright和Python来录制浏览器操作的视频&#…...
一个程序员的牢狱生涯(38)答案
星期一 答 案 我被这个不知道什么时候无声无息的出现在身后的人吓出了一身的冷汗。 看到我发现了他,这个人慢慢地抬起了头……“他X的,是小X州!” 此时的小X州脸上并没有着急等待上厕所的表情,反而是用一种狡黠的眼神看着我。一直充满的敌意,现在又多了一丝威胁的神情,让…...
MySQL命令
目录 1、初级 一、连接和退出 1. 连接到 MySQL 2. 退出 MySQL 二、数据库操作 1. 显示数据库列表 2. 创建数据库 3. 使用数据库 4. 删除数据库 三、表操作 1. 显示当前数据库中的表 2. 创建表 3. 查看表结构 4. 删除表 5. 修改表 四、数据操作 1. 插入数据 2.…...
装本地知识库
装本地知识库 给大模型添加RAG知识库和搜索的功能 1.安装phidata pip install -U phidata在github将该项目拉取下来,后续步骤的很多内容可以直接使用该项目中给的例子,进行简单修改就可直接使用。 2.安装向量知识库,使用的docker docker …...
Django模板层——模板引擎配置
作为Web 框架,Django 需要一种很便利的方法以动态地生成HTML。最常见的做法是使用模板。 模板包含所需HTML 输出的静态部分,以及一些特殊的语法,描述如何将动态内容插入。 模板引擎配置 模板引擎使用该TEMPLATES设置进行配置。这是一个配置列…...
OpenClaw多模型对比:Phi-3-vision-128k-instruct与纯文本模型任务效率实测
OpenClaw多模型对比:Phi-3-vision-128k-instruct与纯文本模型任务效率实测 1. 测试背景与目标 最近在尝试用OpenClaw搭建个人自动化工作流时,遇到了一个实际需求:需要定期从特定网页抓取内容并生成分析报告。这个任务既包含图文信息提取&am…...
避坑指南:天地图加载GeoJSON绘制省市区划时,你可能遇到的3个关键问题与解决方案
天地图加载GeoJSON绘制行政区划的三大核心难题与实战解决方案 当开发者尝试在天地图平台上叠加GeoJSON数据绘制行政区划时,往往会遇到一些意料之外的"坑"。这些问题不仅影响开发效率,更可能导致最终呈现效果与预期相差甚远。本文将聚焦三个最常…...
告别环境冲突:在Anaconda中为PyTorch创建独立的Python 3.10 + CUDA 12.1虚拟环境
深度隔离:用Anaconda构建PyTorchCUDA开发环境的工程化实践 在深度学习项目开发中,环境管理往往是最容易被忽视却最关键的一环。想象一下这样的场景:你正在开发一个基于Transformer的NLP模型,突然需要切换到另一个使用不同CUDA版本…...
化工巡检机器人
山东奇妙智能科技有限公司专注于化工行业智能巡检机器人的研发与应用,其产品旨在通过自动化、智能化技术替代传统人工巡检,提升化工生产环境的安全性、效率和精准度。该类机器人通常具备防爆设计、多传感器融合、自主导航等功能,适用于易燃易…...
CentOS 7.7(基于 RHEL 7 系列)中,账号管理与权限控制是系统安全管理【20260408】001篇
文章目录 一、用户与组管理(本地账号) 1. 用户管理命令 2. 组管理命令 3. 关键配置文件 二、权限控制机制 1. 传统 Linux 权限(UGO + rwx) 2. 特殊权限(慎用) 3. 访问控制列表(ACL)— 突破传统 UGO 限制 三、sudo 权限精细化管理(推荐替代 `su`) 1. 配置原则 2. 最小…...
RAGFlow实战:从零基础到构建企业级AI知识库
在2026年的今天,大模型(LLM)已经不再是新鲜事,但如何将这些“通才”模型转化为企业内部的“专才”,依然是技术落地的核心痛点。检索增强生成(RAG)技术应运而生,而RAGFlow作为一款开源…...
低代码不是妥协,而是进化:.NET 9 AOT+Hot Reload双模引擎深度解析,上线周期压缩至72小时以内
第一章:低代码不是妥协,而是进化:.NET 9 AOTHot Reload双模引擎深度解析,上线周期压缩至72小时以内在传统认知中,“低代码”常被误读为牺牲可控性与性能的权宜之计。而.NET 9通过原生AOT编译与Hot Reload能力的深度融合…...
Matlab串口通信上位机开发:从零搭建实时数据采集系统(附完整代码)
Matlab串口通信上位机开发实战:从零构建工业级数据采集系统 在工业自动化、物联网设备调试和科研实验数据采集领域,串口通信作为最基础也最可靠的数据传输方式,至今仍发挥着不可替代的作用。Matlab凭借其强大的数值计算能力和丰富的可视化工具…...
1995-1996 年阿拉斯加北坡 ARCSS/LAII 通量站点的北极植被样地
Arctic Vegetation Plots at ARCSS/LAII Flux Sites, North Slope, Alaska, 1995-1996 简介 本数据集提供了 1995 年和 1996 年 8 月在北坡北极系统科学/陆地-大气-冰相互作用(ARCSS/LAII)项目通量塔站点采集的植被覆盖、环境样地和土壤数据。19 个 AR…...
Polars 2.0字符串清洗暗雷图谱(含正则引擎变更、Unicode归一化失效、case_when空分支陷阱)
第一章:Polars 2.0字符串清洗暗雷图谱总览Polars 2.0 在字符串处理能力上实现重大跃迁,但其底层惰性求值机制、Unicode 边界行为、空值传播策略及正则引擎差异,共同构成了开发者易踩的“暗雷图谱”。这些隐患往往在大规模 ETL 流程中静默爆发…...
