lwk 8140bc7b08 为MQTT加入延时,防止启动时因为前一个消息还在QS2的握手协议中,后一个消息就到了,导致后一个消息被吞了! 18 hours ago
..
AsyncMsgHandler.cpp 35b773df6a 添加休息队列接收消息! 4 days ago
AsyncMsgHandler.h 35b773df6a 添加休息队列接收消息! 4 days ago
CMakeLists.txt 35b773df6a 添加休息队列接收消息! 4 days ago
LogLocalHelper.cpp 4e5fd41753 为平台层整体添加日志! 2 weeks ago
LogLocalHelper.h 4e5fd41753 为平台层整体添加日志! 2 weeks ago
LogicDevice.cpp 8140bc7b08 为MQTT加入延时,防止启动时因为前一个消息还在QS2的握手协议中,后一个消息就到了,导致后一个消息被吞了! 18 hours ago
LogicDevice.h 8140bc7b08 为MQTT加入延时,防止启动时因为前一个消息还在QS2的握手协议中,后一个消息就到了,导致后一个消息被吞了! 18 hours ago
LogicDevice.rc 20b8172d56 首次提交:平台层代码 2 months ago
LogicDevice.v12.suo 20b8172d56 首次提交:平台层代码 2 months ago
LogicDevice.vcxproj 20b8172d56 首次提交:平台层代码 2 months ago
LogicDevice.vcxproj.filters 20b8172d56 首次提交:平台层代码 2 months ago
LogicDevice.vcxproj.user 20b8172d56 首次提交:平台层代码 2 months ago
MessageInfo.cpp 20b8172d56 首次提交:平台层代码 2 months ago
MessageInfo.h 20b8172d56 首次提交:平台层代码 2 months ago
ReadMe.txt 8140bc7b08 为MQTT加入延时,防止启动时因为前一个消息还在QS2的握手协议中,后一个消息就到了,导致后一个消息被吞了! 18 hours ago
dllmain.cpp 20b8172d56 首次提交:平台层代码 2 months ago
resource.h 20b8172d56 首次提交:平台层代码 2 months ago
stdafx.cpp 20b8172d56 首次提交:平台层代码 2 months ago
stdafx.h 20b8172d56 首次提交:平台层代码 2 months ago
targetver.h 20b8172d56 首次提交:平台层代码 2 months ago

ReadMe.txt

 使用方法

默认行为(无需配置)

# 直接运行,使用默认200ms延时
./your_program

日志输出:
[WaitForBrokerRouting] Using default delay: 200ms (set MQTT_BROKER_ROUTING_DELAY_MS to customize)

自定义延时

Linux/Unix

# 设置为100ms(适用于高性能Broker)
export MQTT_BROKER_ROUTING_DELAY_MS=100
./your_program

# 设置为500ms(适用于嵌入式或低性能设备)
export MQTT_BROKER_ROUTING_DELAY_MS=500
./your_program

# 临时设置(仅当次运行)
MQTT_BROKER_ROUTING_DELAY_MS=50 ./your_program

Windows

REM 设置为100ms
set MQTT_BROKER_ROUTING_DELAY_MS=100
your_program.exe

REM 或在系统环境变量中永久设置

配置建议

根据场景选择延时

| 场景 | 推荐值 | 说明 |
|-----------|------------|-----------------|
| 开发测试 | 50-100ms | 快速迭代,降低等待时间 |
| 生产环境(高性能) | 100-150ms | 现代服务器+高性能Broker |
| 生产环境(默认) | 200ms | 兼顾稳定性和性能 |
| 嵌入式设备 | 300-500ms | 低性能设备或高负载 |
| 极端高负载 | 500-1000ms | 系统资源紧张时 |

调优步骤

1. 初始测试:使用默认200ms,观察是否有消息丢失
2. 逐步减小:如果稳定,尝试150ms → 100ms → 50ms
3. 压力测试:在最小延时下进行快速重启、并发测试
4. 确定最优:找到不丢消息的最小延时值

验证方法

# 1. 快速重启测试(验证稳定性)
for i in {1..10}; do
./your_program &
PID=$!
sleep 2
kill $PID
sleep 1
done

# 2. 检查日志中是否有 "timeout" 或 "not received"
grep -i "timeout\|not received" /path/to/logfile

# 3. 如果有超时,增加延时;如果无超时,可尝试减小延时

技术原理

为什么需要这个延时?

MQTT订阅的两个阶段:
1. 客户端 → Broker: SUBSCRIBE
2. Broker → 客户端: SUBACK ← WaitForSubscriptionComplete确认这一步
3. Broker内部更新路由表 ← WaitForBrokerRouting等待这一步
4. 订阅生效,可以接收消息 ✅

问题:步骤2和步骤3之间的时间间隔不确定,取决于:
- Broker的实现(Mosquitto/EMQ/HiveMQ等)
- 系统负载(CPU/内存/网络)
- 订阅数量(单个vs批量)

为什么不能主动确认?

MQTT协议限制:
- SUBACK只表示"Broker收到SUBSCRIBE"
- 协议没有"路由已生效"的确认机制
- 无法通过发送测试消息验证(会被当作普通消息处理)

为什么设计成可配置?

不同环境差异巨大:
- 云端高性能服务器:20-50ms即可
- 嵌入式设备(如你的OK3588):100-200ms
- 虚拟机或Docker:200-500ms

固定值无法适应所有场景,可配置提供了灵活性。

日志示例

默认配置

[WaitForBrokerRouting] Using default delay: 200ms (set MQTT_BROKER_ROUTING_DELAY_MS to customize)
[WaitForBrokerRouting] LogicClient_xxx - Waiting 200ms for Broker to process subscription routing

自定义配置

[WaitForBrokerRouting] Using custom delay from environment: 100ms
[WaitForBrokerRouting] LogicClient_xxx - Waiting 100ms for Broker to process subscription routing

故障排查

问题:仍然有消息丢失

可能原因:
1. 延时不够 → 增加MQTT_BROKER_ROUTING_DELAY_MS到300或500
2. Broker性能瓶颈 → 检查Broker日志和资源使用
3. 网络延迟 → 检查网络质量(ping、丢包率)

问题:启动太慢

解决方法:
1. 减小延时(如100ms)
2. 如果减小后丢消息,说明Broker性能不足
3. 优化Broker配置或升级硬件