mirror of
https://gitee.com/san-bing/JChargePointProtocol
synced 2026-05-07 19:39:54 +08:00
fix: 修复设备断开后通讯层会话缓存未及时清理的问题
之前设备断开连接时(channelInactive),虽然会关闭会话并通知应用层, 但通讯层的 Caffeine 缓存没有立即清除,导致: - 下行指令仍能找到"幽灵会话",写入已关闭的 channel 后静默失败 - 应用层无法感知设备已离线,用户体验不佳 改动: - ProtocolSession 新增 closeCallback 回调机制,close() 时自动通知注册中心 - ProtocolSession 新增 AtomicBoolean closed 状态,防止重复关闭 - DefaultProtocolSessionRegistryProvider.register() 时自动设置回调 - 新增单元测试验证回调机制 现在设备断开后,App 层下发指令时能立即感知到会话不存在, 并在日志中明确提示"充电桩会话不存在"。
This commit is contained in:
@@ -26,6 +26,8 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
@@ -57,6 +59,17 @@ public abstract class ProtocolSession implements Closeable {
|
||||
@Setter
|
||||
private Forwarder forwarder;
|
||||
|
||||
/**
|
||||
* 会话关闭回调,用于通知注册中心清除缓存
|
||||
*/
|
||||
@Setter
|
||||
private Consumer<UUID> closeCallback;
|
||||
|
||||
/**
|
||||
* 防止重复关闭
|
||||
*/
|
||||
private final AtomicBoolean closed = new AtomicBoolean(false);
|
||||
|
||||
protected ProtocolSession(String protocolName) {
|
||||
this.protocolName = protocolName;
|
||||
this.pileCodeSet = new LinkedHashSet<>();
|
||||
@@ -72,12 +85,29 @@ public abstract class ProtocolSession implements Closeable {
|
||||
}
|
||||
|
||||
public void close(SessionCloseReason reason) {
|
||||
// 防止重复关闭
|
||||
if (!closed.compareAndSet(false, true)) {
|
||||
log.debug("[{}] Protocol会话已关闭,忽略重复关闭请求", this);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("[{}] Protocol会话关闭,原因: {}", this, reason);
|
||||
|
||||
// 1. 取消所有定时任务
|
||||
scheduledFutures.values().forEach(scheduledFuture -> scheduledFuture.cancel(true));
|
||||
scheduledFutures.clear();
|
||||
|
||||
// 转发会话关闭事件到后端
|
||||
// 2. 通知注册中心清除缓存
|
||||
if (closeCallback != null) {
|
||||
try {
|
||||
closeCallback.accept(id);
|
||||
log.debug("[{}] 会话关闭回调执行成功", this);
|
||||
} catch (Exception e) {
|
||||
log.error("[{}] 会话关闭回调执行失败", this, e);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 转发会话关闭事件到后端
|
||||
if (forwarder != null && !pileCodeSet.isEmpty()) {
|
||||
|
||||
for (String pileCode : pileCodeSet) {
|
||||
@@ -106,6 +136,13 @@ public abstract class ProtocolSession implements Closeable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查会话是否已关闭
|
||||
*/
|
||||
public boolean isClosed() {
|
||||
return closed.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user