feat(device): 新增设备在线状态和屏幕状态SSE广播,并修复Redis反序列化问题
- MqttMessageHandler 收到心跳后通过 SseService 广播设备在线状态(含屏幕状态) - SseService/SseSessionManager 新增设备在线状态和屏幕状态的广播方法 - DeviceOnlineServiceImpl 修复 Redis 反序列化为 LinkedHashMap 时的类型转换问题 - DeviceOnlineServiceImpl 修复批量查询时空 SN 导致索引不对齐的问题
This commit is contained in:
@@ -9,6 +9,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import tools.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
@@ -33,6 +34,7 @@ public class DeviceOnlineServiceImpl implements DeviceOnlineService {
|
||||
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
private final MqttProperties mqttProperties;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@Override
|
||||
public void reportHeartbeat(String sn, String ip) {
|
||||
@@ -101,6 +103,14 @@ public class DeviceOnlineServiceImpl implements DeviceOnlineService {
|
||||
if (value instanceof DeviceOnlineVO vo) {
|
||||
return vo;
|
||||
}
|
||||
// GenericJacksonJsonRedisSerializer 反序列化后可能为 LinkedHashMap,需手动转换
|
||||
if (value != null) {
|
||||
try {
|
||||
return objectMapper.convertValue(value, DeviceOnlineVO.class);
|
||||
} catch (Exception e) {
|
||||
log.warn("转换设备在线状态失败, sn={}", sn, e);
|
||||
}
|
||||
}
|
||||
// 离线
|
||||
DeviceOnlineVO offline = new DeviceOnlineVO();
|
||||
offline.setSerialno(sn);
|
||||
@@ -115,12 +125,15 @@ public class DeviceOnlineServiceImpl implements DeviceOnlineService {
|
||||
return result;
|
||||
}
|
||||
List<String> keys = new ArrayList<>(sns.size());
|
||||
// 记录有效 SN 的索引映射,避免空 SN 导致 keys 和 sns 索引不对齐
|
||||
List<String> validSns = new ArrayList<>(sns.size());
|
||||
for (String sn : sns) {
|
||||
if (StrUtil.isBlank(sn)) {
|
||||
continue;
|
||||
}
|
||||
String key = RedisConstants.Device.ONLINE.replace("{}", sn);
|
||||
keys.add(key);
|
||||
validSns.add(sn);
|
||||
// 预置离线状态,供缺失 key 时填充
|
||||
DeviceOnlineVO offline = new DeviceOnlineVO();
|
||||
offline.setSerialno(sn);
|
||||
@@ -132,10 +145,19 @@ public class DeviceOnlineServiceImpl implements DeviceOnlineService {
|
||||
if (values != null) {
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
Object value = values.get(i);
|
||||
String sn = sns.get(i);
|
||||
if (value instanceof DeviceOnlineVO vo) {
|
||||
result.put(sn, vo);
|
||||
String sn = validSns.get(i);
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
// GenericJacksonJsonRedisSerializer 反序列化 multiGet 结果时
|
||||
// 返回 LinkedHashMap,需手动转换为 DeviceOnlineVO
|
||||
DeviceOnlineVO vo;
|
||||
if (value instanceof DeviceOnlineVO v) {
|
||||
vo = v;
|
||||
} else {
|
||||
vo = objectMapper.convertValue(value, DeviceOnlineVO.class);
|
||||
}
|
||||
result.put(sn, vo);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
Reference in New Issue
Block a user