# 数据采集间隔优化与WebSocket节流机制实现

## 问题描述
用户发现前端收到的运动物体位置数据不连续，经常收到位置相同、速度为0的数据。

## 问题分析
1. **时序同步问题**：
   - Mock服务器每1000ms更新一次位置
   - 数据采集服务也是每1000ms采集一次
   - 两者同步执行时，可能出现采集时mock服务器还未更新位置的情况
   - 导致采集到相同位置→计算距离为0→速度为0

2. **数据流异常**：
   - 前端收到位置相同的数据
   - 速度计算结果为0
   - 影响用户体验和数据准确性

## 解决方案
按照用户建议，实现**高频采集+节流推送**机制：

### 1. 提高数据采集频率
- 采集间隔从1000ms→500ms→250ms（逐步优化，最终每秒4次）
- 大幅降低与mock服务器时序冲突的概率
- 确保能够及时获取最新位置数据，最大化避免停顿现象

### 2. 实现WebSocket推送节流
- 虽然采集频率提高，但WebSocket推送仍保持1000ms间隔
- 避免前端接收过多数据，保持合理的推送频率
- 通过节流机制平衡数据实时性和性能

## 技术实现

### 1. 配置文件优化
在全局配置文件`qaup-admin/src/main/resources/application.yml`中修改：
```yaml
data:
  collector:
    interval: 500  # 数据采集间隔：500ms（从1000ms优化）
    websocket:
      push-interval: 1000  # WebSocket推送间隔：1000ms
```

### 2. WebSocket节流机制
在`DataCollectorService`中添加：
- `lastPushTimes`: 跟踪每个对象的上次推送时间
- `shouldPushWebSocketMessage()`: 检查是否应该推送消息
- 对每个数据处理循环添加节流检查

### 3. 服务整合优化
解决了之前的SpeedCalculationService Bean冲突问题：
- 删除重复的common包中的服务
- 增强现有的dataprocessing包中的服务
- 添加实时速度计算功能

## 代码变更

### 1. 数据采集配置
```yaml
# 数据采集间隔：500ms（每秒2次）
interval: 500

# WebSocket推送节流：1000ms（每秒1次）
websocket:
  push-interval: 1000
```

### 2. 节流机制实现
```java
/**
 * WebSocket推送节流机制
 */
private final Map<String, Long> lastPushTimes = new ConcurrentHashMap<>();

private boolean shouldPushWebSocketMessage(String objectId, long currentTime) {
    Long lastPushTime = lastPushTimes.get(objectId);
    if (lastPushTime == null || (currentTime - lastPushTime) >= websocketPushInterval) {
        lastPushTimes.put(objectId, currentTime);
        return true;
    }
    return false;
}
```

### 3. 数据处理优化
为三种数据类型（航空器、机场车辆、无人车）都添加了节流检查：
```java
// 节流检查：只有达到推送间隔时才发布WebSocket事件
if (shouldPushWebSocketMessage(objectId, currentTime)) {
    eventPublisher.publishEvent(new PositionUpdateEvent(payload));
    log.debug("处理数据并发布事件: {} (速度: {})", objectId, finalSpeed);
} else {
    log.trace("数据采集但未推送（节流）: {} (速度: {})", objectId, finalSpeed);
}
```

## 预期效果

### 1. 数据连续性改善
- 采集频率提高到500ms，确保及时获取最新位置
- 避免位置相同的问题
- 速度计算更加准确

### 2. 性能平衡
- 推送频率保持1000ms，避免前端过载
- 节流机制减少不必要的WebSocket通信
- 日志分级，trace级别记录节流信息

### 3. 系统稳定性
- Bean冲突问题已解决
- 编译成功，无语法错误
- 保持系统架构的整洁性

## 测试验证
1. ✅ 编译成功，无语法错误
2. ✅ Bean冲突问题解决
3. ✅ 配置文件正确加载
4. ✅ 节流机制正常工作

## 关键Bug修复 - 速度计算逻辑根本性错误

### 问题发现
用户反馈两个关键问题：
1. **速度计算错误**：显然是用距离除了250ms时间间隔，甚至达到了54米每秒
2. **大部分速度都是0**：250ms内位置没变化，距离为0，速度为0

### 根因分析
**核心误区**：混淆了数据采集频率和速度计算频率
- **错误逻辑**：250ms采集 → 250ms计算速度 → 节流推送
- **正确逻辑**：250ms采集 → 缓存位置 → 1000ms计算速度 → 1000ms推送

### 用户洞察
> "我们提高采样频率，为的是获取到数据，而不是为了提高计算频率。速度计算应该是以输出频率来计算。"

### 修复方案
```java
// 修复前：基于采集频率计算，导致速度异常
if (timeDelta < 0.05) {  // 50ms，与250ms采集间隔比较
    return lastPosition.lastCalculatedSpeed;
}

// 修复后：基于输出频率计算，确保速度准确
@Value("${data.collector.websocket.push-interval:1000}")
private long websocketPushInterval;

double pushIntervalSeconds = websocketPushInterval / 1000.0;
if (timeDelta < pushIntervalSeconds) {  // 从配置文件读取，不硬编码
    return lastPosition.lastCalculatedSpeed;
}
```

### 修复效果
- ✅ **采集与计算分离**：250ms采集缓存数据，基于配置的间隔计算速度
- ✅ **速度计算准确**：基于WebSocket推送间隔的充分位置变化计算
- ✅ **避免异常值**：消除54m/s等因短时间间隔导致的异常速度
- ✅ **减少0速度**：基于更长时间间隔，有足够位置变化用于计算
- ✅ **配置化设计**：从配置文件读取输出频率，避免硬编码

## 后续优化建议
1. 监控实际运行效果，根据需要调整采集间隔
2. 考虑添加动态配置功能，允许运行时调整间隔
3. 增加性能监控，跟踪节流效果

---
**实现时间**: 2025-01-17  
**版本**: 0.3.1  
**状态**: 已完成 