package com.zksy.gas.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.util.Date; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @Component public class DeviceOfflineCheckTask { private static final Logger logger = LoggerFactory.getLogger(DeviceOfflineCheckTask.class); public static ConcurrentHashMap deviceLastReceiveTimeMap = new ConcurrentHashMap<>(); private final Set offlineDeviceSet = ConcurrentHashMap.newKeySet(); @Autowired private RestTemplate restTemplate; @Value("${device.offline.timeout-minutes:30}") private int offlineTimeoutMinutes; @Scheduled(fixedRateString = "${device.offline.check-interval-ms:300000}") public void checkDeviceOffline() { Date now = new Date(); long timeoutMs = (long) offlineTimeoutMinutes * 60 * 1000; for (Map.Entry entry : deviceLastReceiveTimeMap.entrySet()) { long diff = now.getTime() - entry.getValue().getTime(); if (diff > timeoutMs) { if (offlineDeviceSet.add(entry.getKey())) { updateDeviceOnlineStatus(entry.getKey(), 0); logger.info("设备 {} 已离线(超过{}分钟未收到数据)", entry.getKey(), offlineTimeoutMinutes); } } } } public void markDeviceOnline(String deviceCode) { if (offlineDeviceSet.remove(deviceCode)) { updateDeviceOnlineStatus(deviceCode, 1); logger.info("设备 {} 恢复在线", deviceCode); } } private void updateDeviceOnlineStatus(String deviceCode, int onlineStatus) { try { Map params = Map.of("deviceCode", deviceCode, "onlineStatus", onlineStatus); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity> request = new HttpEntity<>(params, headers); restTemplate.postForObject("http://zk-api-service/equipmentStatus/updateOnlineStatus", request, Map.class); } catch (Exception e) { logger.error("更新设备在线状态失败: deviceCode={}, onlineStatus={}", deviceCode, onlineStatus, e); } } }