MQTT 在Spring Boot 中的使用
在 Spring Boot 中使用 MQTT 通常会借助 Spring Integration 项目提供的 MQTT 支持。这使得 MQTT 的集成可以很好地融入 Spring 的消息驱动和企业集成模式。
以下是如何在 Spring Boot 中集成和使用 MQTT 的详细步骤:
前提条件:
- MQTT Broker:需要一个正在运行的 MQTT Broker,例如 Mosquitto, EMQX, HiveMQ, RabbitMQ (with MQTT plugin), Apollo 等。确保 Broker 的地址和端口(默认通常是
tcp://localhost:1883
)。 - Spring Boot 项目:一个基本的 Spring Boot 项目。
步骤 1:添加依赖
在你的 pom.xml
(Maven) 或 build.gradle
(Gradle) 文件中添加必要的依赖:
Maven (pom.xml
):
<dependencies><!-- Spring Boot Starter for core functionality --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- Spring Boot Starter for Web (可选, 如果想通过 REST API 触发 MQTT 发布) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Integration Core --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-integration</artifactId></dependency><!-- Spring Integration MQTT Support --><dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-mqtt</artifactId><!-- Version managed by Spring Boot's BOM, or specify one --></dependency><!-- Eclipse Paho MQTT Client (Spring Integration MQTT uses this) --><dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse.paho.client.mqttv3</artifactId><version>1.2.5</version> <!-- Or a newer compatible version --></dependency>
</dependencies>
步骤 2:配置 MQTT 连接属性
在 src/main/resources/application.properties
(或 application.yml
) 中配置 MQTT Broker 的连接信息:
# MQTT Broker Configuration
mqtt.broker.url=tcp://localhost:1883
mqtt.client.id.publisher=springBootPublisher-unique # 客户端ID,对于每个连接必须唯一
mqtt.client.id.subscriber=springBootSubscriber-unique # 客户端ID,对于每个连接必须唯一
mqtt.default.topic=test/topic
mqtt.qos=1 # 默认的服务质量等级 (0, 1, or 2)# 可选:如果 Broker 需要认证
# mqtt.username=your_username
# mqtt.password=your_password
注意:Client ID 在 MQTT 中必须是唯一的。如果应用同时发布和订阅,可能需要为发布者和订阅者使用不同的 Client ID,或者使用一个 Client ID 但要确保 Paho 客户端实例的正确性。
步骤 3:创建 MQTT 配置类
创建一个 Java 配置类来定义 MQTT 相关的 Bean,如 ClientFactory、出站适配器(用于发布消息)和入站适配器(用于订阅消息)。
package com.example.mqttdemo.config;import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
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.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.handler.annotation.Header;@Configuration
@IntegrationComponentScan // 扫描 @MessagingGateway 等注解
public class MqttConfig {private static final Logger LOGGER = LoggerFactory.getLogger(MqttConfig.class);@Value("${mqtt.broker.url}")private String brokerUrl;@Value("${mqtt.client.id.publisher}")private String publisherClientId;@Value("${mqtt.client.id.subscriber}")private String subscriberClientId;@Value("${mqtt.default.topic}")private String defaultTopic;@Value("${mqtt.qos}")private int defaultQos;// 可选: 如果需要用户名密码认证// @Value("${mqtt.username}")// private String username;// @Value("${mqtt.password}")// private String password;// --- 通用 MQTT Client Factory ---@Beanpublic MqttPahoClientFactory mqttClientFactory() {DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();MqttConnectOptions options = new MqttConnectOptions();options.setServerURIs(new String[]{brokerUrl});// if (username != null && !username.isEmpty()) {// options.setUserName(username);// }// if (password != null && !password.isEmpty()) {// options.setPassword(password.toCharArray());// }options.setCleanSession(true); // 设置为 false 以启用持久会话和离线消息options.setAutomaticReconnect(true); // 启用自动重连options.setConnectionTimeout(10); // 连接超时时间 (秒)options.setKeepAliveInterval(20); // 心跳间隔 (秒)factory.setConnectionOptions(options);return factory;}// --- MQTT 消息发布 (Outbound) ---@Beanpublic MessageChannel mqttOutboundChannel() {return new DirectChannel(); // 或者 PublishSubscribeChannel}@Bean@ServiceActivator(inputChannel = "mqttOutboundChannel")public MessageHandler mqttOutbound(MqttPahoClientFactory clientFactory) {MqttPahoMessageHandler messageHandler =new MqttPahoMessageHandler(publisherClientId, clientFactory); // 使用独立的 Client IDmessageHandler.setAsync(true); // 推荐异步发送messageHandler.setDefaultTopic(defaultTopic); // 默认主题,可以被消息头覆盖messageHandler.setDefaultQos(defaultQos); // 默认QoS,可以被消息头覆盖// messageHandler.setDefaultRetained(false); // 默认是否保留消息return messageHandler;}// 定义一个网关接口,用于发送消息到 mqttOutboundChannel// Spring Integration 会自动实现这个接口@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")public interface MqttGateway {void sendToMqtt(String payload);void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);// 可以定义更多重载方法,例如发送 byte[]// void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, byte[] payload);}// --- MQTT 消息订阅 (Inbound) ---@Beanpublic MessageChannel mqttInputChannel() {return new DirectChannel();}@Beanpublic MqttPahoMessageDrivenChannelAdapter inboundAdapter(MqttPahoClientFactory clientFactory) {// 可以订阅单个主题,或多个主题 (字符串数组)// String[] topicsToSubscribe = {defaultTopic, "another/topic", "sensor/+/data"};MqttPahoMessageDrivenChannelAdapter adapter =new MqttPahoMessageDrivenChannelAdapter(subscriberClientId, clientFactory, defaultTopic); // 使用独立的 Client IDadapter.setCompletionTimeout(5000); // 等待消息发送完成的超时时间adapter.setConverter(new DefaultPahoMessageConverter()); // 消息转换器adapter.setQos(defaultQos); // 订阅时的QoSadapter.setOutputChannel(mqttInputChannel()); // 将接收到的消息发送到此 Channelreturn adapter;}// 消息处理器,处理从 mqttInputChannel 接收到的消息@ServiceActivator(inputChannel = "mqttInputChannel")public void handleIncomingMqttMessage(org.springframework.messaging.Message<String> message) {String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC, String.class);String payload = message.getPayload();Integer qos = message.getHeaders().get(MqttHeaders.RECEIVED_QOS, Integer.class);Boolean retained = message.getHeaders().get(MqttHeaders.RETAINED, Boolean.class);LOGGER.info("Received MQTT Message - Topic: [{}], QoS: [{}], Retained: [{}], Payload: [{}]",topic, qos, retained, payload);// 在这里处理你的业务逻辑}// 可选: 监听 MQTT 事件 (连接成功,连接丢失等)/*@EventListenerpublic void handleMqttEvents(MqttIntegrationEvent event) {LOGGER.info("MQTT Event: {}", event);if (event instanceof MqttConnectionFailedEvent) {MqttConnectionFailedEvent failedEvent = (MqttConnectionFailedEvent) event;LOGGER.error("MQTT Connection Failed!", failedEvent.getCause());} else if (event instanceof MqttSubscribedEvent) {MqttSubscribedEvent subscribedEvent = (MqttSubscribedEvent) event;LOGGER.info("MQTT Subscribed to: {}", subscribedEvent.getMessage());}//还有 MqttMessageSentEvent, MqttMessageDeliveredEvent 等}*/
}
解释:
-
MqttPahoClientFactory
:- 创建和配置底层的 Paho MQTT 客户端。
MqttConnectOptions
用于设置 Broker URL、用户名/密码、Clean Session、Keep Alive、自动重连等。setCleanSession(true)
: 每次连接都是一个全新的会话,断开后 Broker 不会保留订阅信息和离线消息。setCleanSession(false)
: 持久会话,客户端断开重连后,Broker 会尝试发送离线期间的 QoS 1 和 QoS 2 消息,并恢复订阅。需要 Client ID 保持不变。
-
发布消息 (Outbound):
mqttOutboundChannel
: 一个MessageChannel
,作为消息发布的入口。MqttPahoMessageHandler
(mqttOutbound
bean): 这是一个MessageHandler
,它监听mqttOutboundChannel
,并将接收到的消息通过 MQTT 发送出去。- 需要一个
clientId
和MqttPahoClientFactory
。 setAsync(true)
: 异步发送消息,不会阻塞当前线程。setDefaultTopic()
和setDefaultQos()
: 如果消息本身没有指定主题或QoS,则使用这些默认值。
- 需要一个
MqttGateway
: 一个接口,使用@MessagingGateway
注解。Spring Integration 会自动为其生成实现。通过调用这个接口的方法,可以方便的将消息发送到defaultRequestChannel
(即mqttOutboundChannel
)。@Header(MqttHeaders.TOPIC)
和@Header(MqttHeaders.QOS)
允许在发送时动态指定主题和QoS。
-
订阅消息 (Inbound):
mqttInputChannel
: 一个MessageChannel
,入站适配器会将从 MQTT Broker 收到的消息发送到这个 Channel。MqttPahoMessageDrivenChannelAdapter
(inboundAdapter
bean): 这是一个消息驱动的通道适配器,它连接到 MQTT Broker,订阅指定的主题,并将收到的消息推送到outputChannel
(即mqttInputChannel
)。- 需要一个
clientId
、MqttPahoClientFactory
和要订阅的主题(可以是一个或多个,支持通配符)。 setConverter()
: 用于将 MQTT 的byte[]
负载转换为期望的类型(例如String
)。DefaultPahoMessageConverter
可以处理String
和byte[]
。
- 需要一个
handleIncomingMqttMessage
方法: 使用@ServiceActivator(inputChannel = "mqttInputChannel")
注解,监听mqttInputChannel
。当有消息到达时,此方法会被调用。message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)
: 获取消息来源的主题。message.getPayload()
: 获取消息内容。
-
@IntegrationComponentScan
: 确保 Spring Integration 扫描并处理@MessagingGateway
等注解。
步骤 4:使用 MQTT Gateway 发布消息
你可以注入 MqttGateway
到你的 Service 或 Controller 中来发送消息。
示例 Service:
package com.example.mqttdemo.service;import com.example.mqttdemo.config.MqttConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MqttPublishService {private static final Logger LOGGER = LoggerFactory.getLogger(MqttPublishService.class);@Autowiredprivate MqttConfig.MqttGateway mqttGateway;public void publishMessage(String topic, String payload) {try {LOGGER.info("Publishing MQTT message - Topic: [{}], Payload: [{}]", topic, payload);mqttGateway.sendToMqtt(topic, payload);} catch (Exception e) {LOGGER.error("Error publishing MQTT message to topic {}: {}", topic, e.getMessage(), e);}}public void publishMessageWithQos(String topic, String payload, int qos) {try {LOGGER.info("Publishing MQTT message - Topic: [{}], QoS: [{}], Payload: [{}]", topic, qos, payload);mqttGateway.sendToMqtt(topic, qos, payload);} catch (Exception e) {LOGGER.error("Error publishing MQTT message to topic {} with QoS {}: {}", topic, qos, e.getMessage(), e);}}public void publishToDefaultTopic(String payload) {try {LOGGER.info("Publishing MQTT message to default topic, Payload: [{}]", payload);mqttGateway.sendToMqtt(payload); // 将使用 MqttPahoMessageHandler 中配置的默认主题和QoS} catch (Exception e) {LOGGER.error("Error publishing MQTT message to default topic: {}", e.getMessage(), e);}}
}
示例 REST Controller (可选):
package com.example.mqttdemo.controller;import com.example.mqttdemo.service.MqttPublishService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api/mqtt")
public class MqttController {@Autowiredprivate MqttPublishService mqttPublishService;@PostMapping("/publish")public String publishMessage(@RequestParam String topic, @RequestBody String payload) {mqttPublishService.publishMessage(topic, payload);return "Message published to topic: " + topic;}@PostMapping("/publish-default")public String publishToDefault(@RequestBody String payload) {mqttPublishService.publishToDefaultTopic(payload);return "Message published to default topic.";}@PostMapping("/publish-qos")public String publishMessageWithQos(@RequestParam String topic,@RequestParam int qos,@RequestBody String payload) {mqttPublishService.publishMessageWithQos(topic, payload, qos);return "Message published to topic: " + topic + " with QoS: " + qos;}
}
步骤 5:运行和测试
- 启动 MQTT Broker (例如,使用 Docker 运行 Mosquitto):
docker run -it -p 1883:1883 -p 9001:9001 eclipse-mosquitto
- 运行 Spring Boot 应用。
- 测试发布:
- 如果创建了 REST Controller,可以通过 Postman 或 curl 发送 POST 请求:
POST http://localhost:8080/api/mqtt/publish?topic=my/custom/topic
Body (raw, text/plain):Hello from Spring Boot MQTT!
- 或者在应用启动时通过
CommandLineRunner
调用MqttPublishService
。
- 如果创建了 REST Controller,可以通过 Postman 或 curl 发送 POST 请求:
- 测试订阅:
- 当有消息发布到应用订阅的主题 (例如
test/topic
或在inboundAdapter
中配置的其他主题) 时,handleIncomingMqttMessage
方法会被调用,在控制台能看到日志输出。 - 也可以使用 MQTT 客户端工具 (如 MQTTX, MQTT Explorer) 连接到同一个 Broker 并发布消息到被订阅的主题。
- 当有消息发布到应用订阅的主题 (例如
高级主题和注意事项:
- QoS (服务质量等级):
- QoS 0 (At most once): 最多一次,消息可能丢失。
- QoS 1 (At least once): 至少一次,消息可能重复。
- QoS 2 (Exactly once): 精确一次,最可靠但开销最大。
- 可以在
MqttPahoMessageHandler
和MqttPahoMessageDrivenChannelAdapter
中设置默认 QoS,也可以在发送消息时通过MqttHeaders.QOS
动态指定。
- Retained Messages (保留消息):
- 发布者可以将消息标记为 “retained”。Broker 会存储该主题下最新的保留消息。当新客户端订阅该主题时,会立即收到这条保留消息。
- 在
MqttPahoMessageHandler
中设置setDefaultRetained(true)
或通过消息头MqttHeaders.RETAINED
。
- Last Will and Testament (LWT - 遗嘱消息):
- 在
MqttConnectOptions
中配置。如果客户端异常断开,Broker 会发布这个预设的遗嘱消息到指定主题。 options.setWill("client/status", "offline".getBytes(), 1, false);
- 在
- SSL/TLS 加密:
- 如果 Broker 使用 SSL/TLS,需要在
MqttConnectOptions
中配置 SSL 属性,并将 Broker URL 改为ssl://your-broker-address:8883
。 options.setSocketFactory(SslUtil.getSocketFactory("ca.crt", "client.crt", "client.key", "password"));
(需要相应的证书文件和密码)
- 如果 Broker 使用 SSL/TLS,需要在
- 错误处理:
- Spring Integration 提供了错误通道 (
errorChannel
) 来处理消息传递过程中的异常。 - 可以监听
MqttIntegrationEvent
(如MqttConnectionFailedEvent
) 来获取连接状态事件。
- Spring Integration 提供了错误通道 (
- Client ID 唯一性:再次强调,连接到同一个 Broker 的每个 MQTT 客户端都必须有唯一的 Client ID。如果发布和订阅逻辑在同一个应用实例中,并且为它们配置了相同的 Client ID 但使用了不同的
MqttPahoClientFactory
实例或适配器,Paho 库内部可能会产生冲突或意外行为。建议为出站和入站适配器使用不同的 Client ID,或者共享一个MqttPahoClientFactory
实例(确保它能正确处理这种情况)。 - Converter (转换器):
DefaultPahoMessageConverter
默认将String
转换为byte[]
发送,接收时根据目标类型尝试转换。如果需要处理 JSON 或其他复杂类型,需要自定义MessageConverter
或在消息处理器中进行序列化/反序列化。
相关文章:
MQTT 在Spring Boot 中的使用
在 Spring Boot 中使用 MQTT 通常会借助 Spring Integration 项目提供的 MQTT 支持。这使得 MQTT 的集成可以很好地融入 Spring 的消息驱动和企业集成模式。 以下是如何在 Spring Boot 中集成和使用 MQTT 的详细步骤: 前提条件: MQTT Brokerÿ…...
uniapp使用全局组件,
在 Uniapp 中,如果你的组件是应用层组件(例如全局悬浮按钮、全局通知栏等),并且希望它自动出现在所有页面而无需在每个页面模板中手动添加组件标签,可以通过以下两种方案实现: 方案一:通过 app.…...
【三维重建】三维场景生成:综述
标题:《3D Scene Generation: A Survey》 来源:新加坡南洋理工大学 项目:https://github.com/hzxie/Awesome-3D-Scene-Generation 文章目录 摘要一、前言二、准备工作2.1 任务定义2.2 三维场景表示2.3 生成模型 三、方法:分层分类…...
怎样将MM模块常用报表设置为ALV默认格式(MB52、MB5B、ME2M、ME1M等)
【SAP系统研究】 对SAP系统中的报表,最方便的格式就是ALV了,可排序、可导出,非常友好。 但有些常见报表却不是默认ALV界面的,譬如MB52: 是不是有点别扭?但其实是可以后台配置进行调整的。 现将一些常用报表修改为默认ALV的方法进行总结,便于大家使用。 一、MB52、MB5…...
Flutter 开发入门:从一个简单的计数器应用开始
在当今快速发展的移动应用开发领域,Flutter 框架以其高效、跨平台的特点脱颖而出,成为许多开发者的首选。本文将通过一个简单的 Flutter 项目代码,带你深入了解 Flutter 开发的基本概念和流程。这个项目是一个简单的计数器应用,它…...
Python解释器、REPL与脚本的区别
用ChatGPT做软件测试 “初学者写代码,高手理解运行。” 要成为真正理解代码的人,必须透彻理解:Python 是如何运行你的代码的?解释器、REPL 和脚本之间的界限与联系究竟是什么? 一、编程学习常见误区:把“运…...
总共76dp 空出20dp然后放一个控件的写法
<FrameLayout android:id"id/bt_user_agree" android:layout_width"120dp" android:layout_height"76dp" > <ImageView android: 这里里上一个 android:layout_width"wrap_content" android:layout_height"40dp" …...
【PmHub后端篇】PmHub集成 Sentinel+OpenFeign实现网关流量控制与服务降级
在微服务架构中,保障服务的稳定性和高可用性至关重要。本文将详细介绍在 PmHub 中如何利用 Sentinel Gateway 进行网关限流,以及集成 Sentinel OpenFeign 实现自定义的 fallback 服务降级。 1 熔断降级的必要性 在微服务架构中,服务间的调…...
C#扩展方法的入门理解
public static class CanGetModelExtension {public static T GetModel<T>(this ICanGetModel self) where T : class, IModel >self.GetArchitecture().GetModel<T>(); } 前言: 在学习QFramework时,看底层框架代码注意到这个函数&#…...
HTML应用指南:利用POST请求获取全国圆通快递服务网点位置信息
圆通快递作为国内物流行业的领军企业,自2000年成立以来,始终秉持 “客户要求,圆通使命” 的服务宗旨,致力于为客户提供高效、优质的物流服务。凭借其庞大的物流网络、先进的信息技术以及卓越的运营管理,圆通快递在激烈…...
vulnhub靶场——secarmy
靶机:secarmy靶机,IP地址为192.168.230.18 攻击:kali,IP地址为192.168.230.134 靶机和攻击机都采用VMware虚拟机,都采用NAT模式 端口扫描: nmap 192.168.230.18 -O -A -p- --reason -sV 21/tcp (ftp): 开…...
Daily AI 20250514 (迁移学习与元学习)
参考资料:神经网络与深度学习 目录 迁移学习 (Transfer Learning)归纳迁移学习转导迁移学习 元学习 (Meta Learning)基于优化器的元学习模型无关的元学习(Model-AgnosticMeta-Learning,MAML&am…...
牛市买卖数字货币逻辑
在牛市中进行数字货币交易,核心逻辑是顺势而为、控制风险、把握周期。以下是关键策略和逻辑框架: 一、牛市的核心逻辑 资金驱动 牛市由增量资金(新投资者、机构资金、杠杆资金)推动,流动性充裕时,市场情绪乐…...
7.DTH11和PWM波
目录 室内/本地温湿度检测 温湿度传感器介绍 获取手册和例程的方法 从手册中提取重要信息 传感器的分类 温度传感器类型 DHT11 的介绍 温湿度传感器的接口 温湿度传感器的时序 温湿度传感器电路介绍 IO 的配置 定时器输出 PWM 波 PWM 波介绍 PWM 波的作用&#x…...
在UI 原型设计中,交互规则有哪些核心要素?
在UI 原型设计中,交互规则主要有三个核心要素,分别为重要性、原则与实践,具体表现在: 一、交互规则在 UI 原型设计中的重要性 明确交互逻辑:设计阶段制定交互规则,清晰定义界面元素操作响应。 如社交应用…...
树的直径 | 树的最长路径
树的直径: 树上任意两节点之间最长的简单路径即为树的「直径」。 定理: 在一棵树上,从任意节点 u 开始进行一次 DFS,到达的距离其最远的节点 v 必为直径的一端。 B4016 树的直径 - 洛谷 思路: 由于这题中每条边的…...
AbMole解读:脂质体的关键组分和主要合成方法
脂质体(Liposome)是一种由磷脂等两性分子自发形成的封闭囊泡结构,随着纳米技术、材料科学等多学科的交叉发展,脂质体的研究与应用进入了一个新的阶段,并在肿瘤研究、疫苗研发、基因递送等多个领域发挥着关键作用。AbMo…...
Python爬虫之品牌口碑数据抓取
上一篇我们介绍了爬虫营销的优势,这次我就展开详细的说说,如何通过爬取社交媒体或电商平台的公开评论来分析自己或竞争对手的品牌声誉。 选择微博这样的平台,因为它的数据相对公开,而且有API支持,但要注意频率限制和反…...
【android bluetooth 协议分析 12】【A2DP详解 1】【车机侧蓝牙音乐免切源介绍】
“车机蓝牙音乐免切源” 是近年来车载系统(IVI,In-Vehicle Infotainment)中常见的一个用户体验优化功能。它主要是为了简化蓝牙音乐播放流程、减少用户操作,提升使用便捷性。 一、什么是“切源”? 在车机系统中&#…...
眼镜店哪个品牌好,你会选择哪一款眼镜
有些人买眼睛是为了耍帅,有些人买眼镜,可能就是为了调节视力。现在手机以及其他的电子产品越来越普及,近视眼的人群是越来越多了,那么要准备去配眼镜的话,就要找到一个正规的眼镜店,一起来了解一下眼镜店哪…...
基于EFISH-SCB-RK3576/SAIL-RK3576的畜禽养殖监控仪技术方案
(国产化替代J1900的农业物联网解决方案) 一、硬件架构设计 多源环境感知模块 空气质量监测: 集成NH₃/CO₂/H₂S三合一气体传感器(量程0-500ppm,精度2%FS),采样间隔≤1秒激光粉尘检测…...
linux - 权限的概念
目录 用户权限 超级用户与普通用户的区别 超级用户(root): 普通用户: 切换用户身份 使用sudo执行高权限命令 用户管理 用户组管理 文件权限 文件访问者类别 基本权限 权限表示方法 权限修改 chmod chown chgrp u…...
LeRobot 框架的核心架构概念和组件(中)
本文档概述构成 LeRobot 框架的核心架构概念和组件。它介绍主要的子系统,并解释它们如何相互作用以实现机器人学习。 。。。。。。继续。。。。。。 环境接口 环境系统提供与模拟环境交互的统一接口。这些环境允许在部署到物理机器人之前,在受控环境中…...
鸿蒙5.0项目开发——鸿蒙天气项目的实现(主页1)
【高心星出品】 文章目录 页面效果:页面功能:页面执行流程:1. 页面初始化阶段2. 定位获取阶段3. 天气数据加载阶段 这个页面是整个天气应用的核心,集成了天气查询、定位、搜索等主要功能,提供了完整的天气信息服务。 …...
虚幻引擎5-Unreal Engine笔记之摄像机与场景捕获相关概念的解析
虚幻引擎5-Unreal Engine笔记之摄像机与场景捕获相关概念的解析 code review! 文章目录 虚幻引擎5-Unreal Engine笔记之摄像机与场景捕获相关概念的解析1. UE中SceneCapture和UCameraComponent的关系是什么?Camera和SceneCapture2D的关系是什么1.1 UCameraComponen…...
【vim】--- vim 插件说明 超详细持续更新中
在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。【vim】--- vim 插件说明 超详细持续更新中 开发环境一、vim 插件管理器1、Vim-Plug2…...
医学影像系统的集成与工作流优化
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…...
Vue 和 React 状态管理的性能优化策略对比
一、Vue 状态管理优化策略 合理使用 Vuex 模块化 将全局状态拆分为模块,按需加载,避免单一 Store 文件过大。通过命名空间隔离状态,减少状态冗余和无效更新。 const moduleA { namespaced: true, state: { /* ... */ } }; const store new …...
python打包exe报错:处理文件时错误:Excel xlsx file; not supported
背景:最近用python写一个excel解析工具,然后打包成exe可执行文件的时候,遇到这样的问题 1.在我自己编译器运行是可以正常将上传后的excel进行解析,但是在打包成exe后,就无法正常解析excel 问题排查: 1.切换…...
libmemcached库api接口讲解一
前言:好多接口的用法都不怎么会,得学习一下具体的用法 memcached_st ✅ 一个连接 memcached 服务集群的“客户端实例”对象,用于管理连接、执行读写操作、设置行为、维护哈希环等一切功能。 它在使用中通常通过下面的方式创建: …...
【RabbitMQ】发布确认机制的具体实现
文章目录 模式介绍建立连接单独确认代码实现逻辑运行结果 批量确认代码实现逻辑运行结果 异步确认实现逻辑介绍代码实现逻辑运行结果 三种策略对比以及完整代码 模式介绍 作为消息中间件,都会面临消息丢失的问题,消息丢失大概分为三种情况: …...
RabbitMQ是什么?应用场景有哪些?
RabbitMQ 是一款开源的消息代理中间件,基于 AMQP(高级消息队列协议)实现,用于在分布式系统中进行异步通信和消息传递。它通过将消息的发送者和接收者解耦,提高了系统的可扩展性、可靠性和灵活性。 核心特点 多协议支持:不仅支持 AMQP,还兼容 STOMP、MQTT 等多种消息协议…...
数学实验(Matlab符号运算)
一、符号对象的建立 Matlab符号运算特点 计算以推理方式进行,因此不受计算误差积累所带来的困扰 符号计算指令的调用比较简单,与数学教科书上的公式相近 Matlab符号运算举例 符号对象与符号表达式 在进行符号运算时,必须先定义基本的符号…...
使用 hover-class 实现触摸态效果 - uni-app 教程
目录 一、什么是 hover-class 二、常用组件支持 hover-class 三、基本 效果说明: 四、配合 hover-start-time 和 hover-stay-time 五、注意事项 六、实践建议 在移动端开发中,良好的用户交互体验尤为重要,点击或长按某个按钮时&#x…...
# 深度剖析LLM的“大脑”:单层Transformer的思考模式探索
简单说一下哈 —— 咱们打算训练一个单层 Transformer 加上稀疏自编码器的小型百万参数大型语言模型(LLM),然后去调试它的思考过程,看看这个 LLM 的思考和人类思考到底有多像。 LLMs 是怎么思考的呢? 开源 LLM 出现之后…...
Git仓库迁移
前言 前面我讲了GitLab搭建与使用(SSH和Docker)两种方式,那么就会延伸出来一个情况:Git仓库迁移虽然这种情况很少发生,但是我自己公司近期要把 阿里云迁移到华为云,那么放在上面的Git仓库也要全量迁移下面我就写了一个脚本演示&am…...
Windows避坑部署CosyVoice多语言大语言模型
#工作记录 前言 在实际部署与应用过程中,项目的运行环境适配性对其稳定性与功能性的发挥至关重要。CosyVoice 项目虽具备强大的语音处理能力,但受限于开发与测试环境的侧重方向,其对运行环境存在特定要求。 该项目在 Linux 和 Docker 生态…...
《实现模式》以Golang视角解读 价值观和原则 day 1
为什么阅读实现模式? 为什么阅读《实现模式》?Kent Beck 的《实现模式》其核心思想——编写清晰、易于理解且易于维护的代码,对于软件工程的新手而言,直接深入复杂的设计模式或架构理念可能会感到困惑。《实现模式》则弥合了设计…...
解决 PicGo 上传 GitHub图床及Marp中Github图片编译常见难题指南
[目录] 0.行文概述 1.PicGo图片上传失败 2.*关于在Vscode中Marp图片的编译问题* 3.总结与启示行文概述 写作本文的动机是本人看到了Awesome Marp,发现使用 Markdown \texttt{Markdown} Markdown做PPT若加持一些 CSS , JavaScript \texttt{CSS},\texttt{JavaScript} …...
LeetCode 820 单词的压缩编码题解
LeetCode 820 单词的压缩编码题解 题目描述 题目链接 给定一个单词列表,将其编码为一个索引字符串S,格式为"单词1#单词2#…"。要求当某个单词是另一个单词的后缀时,该单词可以被省略。求最终编码字符串的最小长度。 解题思路 逆…...
Windows软件插件-写wav
下载本插件 本插件,将PCM音频流写入WAV音频文件。或将PCM音频流压缩为ALAW格式,写入WAV文件。可以创作大文件(超过4字节所能表示的大小)。插件类型为DLL,可以在win32和MFC程序中使用。使用本插件创建的ALAW格式WAV音频…...
基于 Spring Boot 瑞吉外卖系统开发(十五)
基于 Spring Boot 瑞吉外卖系统开发(十五) 前台用户登录 在登录页面输入验证码,单击“登录”按钮,页面会携带输入的手机号和验证码向“/user/login”发起请求。 定义UserMapper接口 Mapper public interface UserMapper exte…...
【Linux高级IO】多路转接之epoll
多路复用之epoll 一,认识epoll二,epoll的相关接口1. epoll_create2. epoll_ctl3. epoll_wait 三,epoll的原理四,epoll的两种工作模式(ET和LT)1. 两种工作模式2. 对比ET和LT 五,总结 在了解到sel…...
Java 性能调优全解析:从设计模式到 JVM 的 7 大核心方向实践
引言 在高并发、低延迟的技术场景中,Java 性能优化需要系统化的方法论支撑。本文基于7 大核心优化方向(复用优化、计算优化、结果集优化、资源冲突优化、算法优化、高效实现、JVM 优化),结合权威框架与真实案例,构建从…...
“海外滴滴”Uber的Arm迁移实录:重构大规模基础设施
云工作负载在性价比上的自然演进路径: Intel ➜ AMD ➜ ARM 不信?来看看 Uber 的做法: 01/Arm架构:云计算新时代 2023 年 2 月,Uber 正式开启了一项战略性迁移:将从本地数据中心迁移至云端,…...
java加强 -File
File类的对象可以代表文件/文件夹,并可以调用其提供的方法对象文件进行操作。 File对象既可以代表文件,也可以代表文件夹。 创建File对象,获取某个文件的信息 语法: File 对象名 new File("需要访问文件的绝对路径&…...
SQL注入 ---04
1 简单的sql注入 要求: 要有sql注入: 1,变量 2,变量要带入数据库进行查询 3,没有对变量进行过滤或者过滤不严谨 mysql> select * from users where id2 limit 0,1; 当我的语句这样写时查寻到的结果 当我修改为&…...
MySQL知识点总结(持续更新)
聚合函数通常用于对数据进行统计和聚合操作。以下是一些常见数据库系统(如 MySQL、PostgreSQL、Oracle、SQL Server 等)中常用的聚合函数: 常见的数据库聚合函数: COUNT():计算指定列中非空值的数量 SELECT COUNT(*) …...
数字信号处理-大实验1.1
MATLAB仿真实验目录 验证实验:常见离散信号产生和实现验证实验:离散系统的时域分析应用实验:语音信号的基音周期(频率)测定 目录 一、常见离散信号产生和实现 1.1 实验目的 1.2 实验要求与内容 1.3 实验…...
Qt操作SQLite数据库教程
Qt 中操作 SQLite 数据库的步骤如下: 1. 添加 SQLite 驱动并打开数据库 #include <QSqlDatabase> #include <QSqlError> #include <QSqlQuery>// 创建数据库连接 QSqlDatabase db QSqlDatabase::addDatabase("QSQLITE"); db.setData…...