Optimize radar command code

This commit is contained in:
longguancheng 2026-02-05 14:13:26 +08:00
parent f2f829a2f8
commit 5946d692c5

View File

@ -23,6 +23,7 @@ import java.io.IOException;
import java.net.DatagramPacket; import java.net.DatagramPacket;
import java.net.DatagramSocket; import java.net.DatagramSocket;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -110,49 +111,88 @@ public class SarControlContext {
*/ */
private void sendUdp(SarControlDTO control) { private void sendUdp(SarControlDTO control) {
SarControlTypeEnum controlType = control.getControlType(); SarControlTypeEnum controlType = control.getControlType();
String ip = control.getIp(); String targetIp = control.getIp();
log.debug("开始发送雷达控制指令[{}]", controlType); log.info("准备发送雷达控制指令 | 类型:{} | 目标IP:{}", controlType, targetIp);
String cacheKey = CacheKey.getSarControlBack(targetIp);
byte[] payload;
try {
payload = pack(control);
} catch (Exception e) {
log.error("打包控制指令失败 | 类型:{} | ip:{} | {}", controlType, targetIp, e.getMessage(), e);
throw new ServiceException("控制指令打包失败:" + e.getMessage());
}
try (DatagramSocket socket = new DatagramSocket()) { try (DatagramSocket socket = new DatagramSocket()) {
byte[] content = pack(control); InetSocketAddress address = new InetSocketAddress(targetIp, PORT);
socket.connect(new InetSocketAddress(ip, PORT)); socket.connect(address);
DatagramPacket packet = new DatagramPacket(content, content.length); DatagramPacket packet = new DatagramPacket(payload, payload.length);
int failCount = 0; SarErrorDTO response = null;
SarErrorDTO info = null; int retryCount = 0;
String cacheKey = CacheKey.getSarControlBack(ip); // skyeye:sar:control + ip while (response == null && retryCount < RETRY_MAX) {
while (info == null && failCount < RETRY_MAX) { // 发送
try {
socket.send(packet); socket.send(packet);
// 每0.1秒取回执1秒后超时 log.info("UDP指令已发送 | 第{}次尝试 | 类型:{} | ip:{}",
long startTime = System.currentTimeMillis(); retryCount + 1, controlType, targetIp);
while (System.currentTimeMillis() - startTime < ANSWER_TIMEOUT) { } catch (IOException e) {
// Caffeine 获取 log.warn("发送UDP失败 | 第{}次尝试 | {}", retryCount + 1, e.getMessage());
Cache shortCache = cacheManager.getCache("sar-short-lived"); retryCount++;
info = CacheUtil.get(shortCache, cacheKey, SarErrorDTO.class); continue;
if (info != null) { }
shortCache.evict(cacheKey); // 相当于 del读取后删除 // 等待回执轮询方式
break; response = waitForResponse(cacheKey, targetIp, controlType);
} else { if (response == null) {
retryCount++;
log.warn("第{}次发送未收到回执 | 类型:{} | ip:{}", retryCount, controlType, targetIp);
}
}
// 最终判断
if (response == null) {
String msg = String.format("雷达[%s]控制指令[%s]发送失败:超时无应答", targetIp, controlType);
log.error(msg);
throw new SarConnectException(msg + ",请重试");
}
// 业务状态判断
if (response.getExecStatus() == 1) {
String msg = String.format("雷达[%s]控制指令[%s]执行失败:状态码=1数据结构错误",
targetIp, controlType);
log.error(msg);
throw new ServiceException(msg + ",请检查指令内容后重试");
}
log.info("雷达控制指令发送成功 | 类型:{} | ip:{} | 状态:{}", controlType, targetIp, response.getExecStatus());
} catch (IOException e) {
String msg = String.format("雷达控制指令[%s]网络异常 | ip:%s | %s", controlType, targetIp, e.getMessage());
log.error(msg, e);
throw ServiceException.errorLog(msg);
}
}
/**
* 轮询等待缓存中的回执带超时
*/
private SarErrorDTO waitForResponse(String cacheKey, String ip, SarControlTypeEnum controlType) {
Cache sarShortCache = cacheManager.getCache("sar-short-lived");
if (sarShortCache == null) {
log.error("无法获取 sar-short-lived cache");
return null;
}
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < ANSWER_TIMEOUT) {
SarErrorDTO dto = CacheUtil.get(sarShortCache, cacheKey, SarErrorDTO.class);
if (dto != null) {
// 读后即删防止重复消费
sarShortCache.evict(cacheKey);
log.info("收到雷达回执 | ip:{} | 控制类型:{} | 状态:{}", ip, controlType, dto.getExecStatus());
return dto;
}
try { try {
Thread.sleep(POLLING_INTERVAL); Thread.sleep(POLLING_INTERVAL);
} catch (InterruptedException e) { } catch (InterruptedException e) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
log.warn("等待雷达回执时被中断 | ip:{}", ip);
return null;
} }
} }
} return null; // 超时
if (info == null) { // 超时未收到回执
failCount++;
} else if (info.getExecStatus() == 1) {
// 只有发送的数据结构错误时才会返回错误状态并不会因为业务不允许返回错误
throw new ServiceException("控制指令[" + controlType + "]执行状态错误,请重试");
}
}
if (info == null) {
throw new SarConnectException("控制指令[" + controlType + "]发送失败,雷达[" + ip + "]无应答,请重试");
} else {
log.info("雷达控制指令[{}]发送完毕----------------------", controlType);
}
} catch (IOException ex) {
throw ServiceException.errorLog("控制指令[" + controlType + "]发送失败 " + ex.getMessage());
}
} }
/** /**