Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cursor-usage-example
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
岳建彬
cursor-usage-example
Commits
89f0c9cf
Commit
89f0c9cf
authored
Jun 26, 2025
by
岳建彬
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add Cursor 快速解决客户端重连问题示例
parent
896af18c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
267 additions
and
0 deletions
+267
-0
20250626Cursor快速解决EMQX客户端断开重连问题修复.md
cases/backend/20250626Cursor快速解决EMQX客户端断开重连问题修复.md
+185
-0
README.md
cases/backend/README.md
+47
-0
README.md
cases/backend/original-conversations/README.md
+35
-0
cursor-emqx-mqtt-reconnect-conversation.md
...-conversations/cursor-emqx-mqtt-reconnect-conversation.md
+0
-0
No files found.
cases/backend/20250626Cursor快速解决EMQX客户端断开重连问题修复.md
0 → 100644
View file @
89f0c9cf
# Spring Boot 集成 EMQX 客户端重连与订阅恢复
# Spring Boot 集成 EMQX 客户端重连与订阅恢复
> **场景**: 解决微服务重启后 EMQX 客户端连接断开,但服务端订阅状态不同步的问题
>
> **技术栈**: Spring Boot + MQTT + EMQX
>
> **作者**: 基于 Cursor AI 对话整理
> **日期**: 2025-06-26
---
## 问题描述
在微服务架构中,当云服务重启后,会出现以下问题:
-
EMQX 服务端客户端连接断开
-
订阅者在服务端依然存在
-
客户端重连后订阅状态不同步
## 使用 Cursor 的解决过程
### 1. 问题诊断 Prompt
```
@/micro-cloud-adapter cloud 服务重启后 会 emqx 服务端 客户端断开了连接,但是订阅者在服务端还依然存在,该如何解决
```
### 2. 代码分析与解决方案
#### 问题根因分析
Cursor 分析后发现主要问题:
1.
**clientId 使用 UUID**
: 每次服务重启都会生成新的 clientId,导致 EMQX 无法识别同一客户端
2.
**cleanSession 设置**
: 会话持久化配置不当
3.
**缺少重连机制**
: 没有在重连后立即恢复订阅的机制
#### 解决方案代码
**优化后的 MqttConfig 配置类**
:
```
java
@Configuration
public
class
MqttConfig
{
@Value
(
"${spring.application.name}"
)
private
String
applicationName
;
@Autowired
private
MqttTopicService
mqttTopicService
;
/**
* 生成固定的 clientId,基于应用名和主机信息
* 确保服务重启后 clientId 保持一致
*/
private
String
getFixedClientId
()
{
try
{
String
hostName
=
InetAddress
.
getLocalHost
().
getHostName
();
return
applicationName
+
"-"
+
hostName
+
"-service"
;
}
catch
(
Exception
e
)
{
return
applicationName
+
"-service"
;
}
}
@Bean
public
MqttPahoClientFactory
mqttClientFactory
()
{
DefaultMqttPahoClientFactory
factory
=
new
DefaultMqttPahoClientFactory
();
MqttConnectOptions
options
=
new
MqttConnectOptions
();
// 关键配置:使用固定 clientId
options
.
setClientId
(
getFixedClientId
());
options
.
setCleanSession
(
false
);
// 保持会话持久化
options
.
setAutomaticReconnect
(
true
);
// 自动重连
options
.
setKeepAliveInterval
(
60
);
options
.
setConnectionTimeout
(
30
);
factory
.
setConnectionOptions
(
options
);
return
factory
;
}
}
```
**添加连接状态监听器**
:
```
java
@Component
@Slf4j
public
class
MqttConnectionCallback
implements
MqttCallback
{
@Autowired
private
MqttTopicService
mqttTopicService
;
@Override
public
void
connectionLost
(
Throwable
cause
)
{
log
.
warn
(
"MQTT连接丢失: {}"
,
cause
.
getMessage
());
}
@Override
public
void
connectComplete
(
boolean
reconnect
,
String
serverURI
)
{
if
(
reconnect
)
{
log
.
info
(
"MQTT重连成功,开始恢复订阅"
);
// 重连后立即恢复订阅
restoreSubscriptions
();
}
}
private
void
restoreSubscriptions
()
{
try
{
List
<
String
>
topics
=
mqttTopicService
.
getAllTopics
();
// 重新订阅所有主题
mqttTopicService
.
subscribeTopics
(
topics
);
log
.
info
(
"订阅恢复完成,共恢复 {} 个主题"
,
topics
.
size
());
}
catch
(
Exception
e
)
{
log
.
error
(
"恢复订阅失败"
,
e
);
}
}
}
```
### 3. 效果验证
使用 Cursor 生成的测试用例:
```
java
@Test
public
void
testReconnectAndSubscribe
()
{
// 模拟服务重启
mqttClient
.
disconnect
();
// 验证重连后订阅状态
mqttClient
.
connect
();
// 检查订阅是否正常恢复
List
<
String
>
activeTopics
=
mqttTopicService
.
getActiveSubscriptions
();
assertThat
(
activeTopics
).
isNotEmpty
();
}
```
## 关键配置总结
| 配置项 | 推荐值 | 说明 |
|--------|--------|------|
|
`clientId`
| 基于应用名+主机名 | 确保重启后一致性 |
|
`cleanSession`
|
`false`
| 保持会话持久化 |
|
`automaticReconnect`
|
`true`
| 启用自动重连 |
|
`keepAliveInterval`
|
`60`
| 心跳间隔 |
## 使用体验
### Cursor 的优势
-
快速定位问题根因
-
提供完整的代码解决方案
-
自动生成相关测试用例
### 注意事项
-
需要根据实际项目结构调整包名和类名
-
SSL 配置需要根据实际证书路径调整
-
监听器注册需要确保在 Spring 容器中正确装配
---
## 相关资源
-
[
EMQX 官方文档
](
https://www.emqx.io/docs
)
-
[
Spring Integration MQTT
](
https://docs.spring.io/spring-integration/reference/html/mqtt.html
)
-
[
Eclipse Paho MQTT Client
](
https://www.eclipse.org/paho/clients/java/
)
-
[
完整对话记录
](
./original-conversations/cursor-emqx-mqtt-reconnect-conversation.md
)
- 查看与 Cursor AI 的完整问题分析过程
## 扩展思考
1.
**集群环境下的 clientId 策略**
2.
**订阅主题的动态管理**
3.
**消息重复处理机制**
4.
**监控与告警集成**
---
## 💡 学习建议
想要了解完整的问题分析过程?点击查看
[
原始 Cursor 对话记录
](
./original-conversations/cursor-emqx-mqtt-reconnect-conversation.md
)
,包含:
-
AI 的完整分析思路
-
多轮问题诊断过程
-
代码生成和优化过程
-
测试验证方案推导
\ No newline at end of file
cases/backend/README.md
0 → 100644
View file @
89f0c9cf
# Backend 案例集合
> 收集后端开发中使用 Cursor 的典型案例和最佳实践
## Java 案例
### 1. Spring Boot 集成 EMQX 客户端重连与订阅恢复
**文件**
:
`spring-boot-emqx-integration.md`
**场景**
: 解决微服务重启后 EMQX 客户端连接断开,但服务端订阅状态不同步的问题
**关键技术**
:
-
Spring Boot + MQTT 集成
-
客户端重连机制
-
订阅状态恢复
-
连接监听器实现
**使用收益**
:
-
快速定位 MQTT 连接问题根因
-
自动生成完整的解决方案代码
-
提供测试验证方案
---
## 添加新案例
如需添加新的后端案例,请遵循以下格式:
1.
文件命名:
`技术栈-具体场景.md`
2.
内容结构:
-
问题描述
-
使用 Cursor 的解决过程
-
关键代码片段
-
效果验证
-
使用体验总结
## 技术栈覆盖
-
[
x
]
Spring Boot + MQTT
-
[
]
Spring Cloud 微服务
-
[
]
MyBatis Plus 数据库操作
-
[
]
Redis 缓存集成
-
[
]
RabbitMQ 消息队列
-
[
]
ElasticSearch 搜索
-
[
]
Docker 容器化
\ No newline at end of file
cases/backend/original-conversations/README.md
0 → 100644
View file @
89f0c9cf
# 原始对话备份
> 此文件夹保存与 Cursor AI 的完整对话记录,供参考和学习使用
## 文件说明
### `cursor-emqx-mqtt-reconnect-conversation.md`
-
**原始问题**
: 解决 EMQX 服务端客户端断开问题
-
**对话日期**
: 2025-06-26
-
**技术栈**
: Spring Boot + MQTT + EMQX
-
**解决方案**
: 客户端重连与订阅恢复机制
## 使用说明
1.
这些文件保存了完整的 Cursor AI 对话过程
2.
可以点击文件链接查看详细的问题分析过程
3.
包含了 AI 的思考过程和多轮对话交互
4.
适用于:
-
学习 Cursor AI 的使用技巧
-
了解问题分析的完整思路
-
复现类似问题的解决过程
## 文件结构
```
original-conversations/
├── README.md # 本说明文件
├── cursor-emqx-mqtt-reconnect-conversation.md # EMQX 重连问题完整对话
└── [其他对话备份...]
```
---
**注意**
: 这些文件包含完整的 AI 对话导出,可能包含调试信息和多次尝试的过程,与
`cases/backend/`
中的精简案例不同。
\ No newline at end of file
cases/backend/original-conversations/cursor-emqx-mqtt-reconnect-conversation.md
0 → 100644
View file @
89f0c9cf
This source diff could not be displayed because it is too large. You can
view the blob
instead.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment