fix:协议驱动完善+工厂类

This commit is contained in:
2026-03-20 10:23:41 +08:00
parent c1696110a9
commit 3f8193a593
8 changed files with 322 additions and 99 deletions

View File

@@ -0,0 +1,70 @@
package org.nl.iot.core.driver;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.exception.CommonException;
import org.nl.iot.core.driver.service.DriverCustomService;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 抽象驱动类
* @Author: liyongde
* @Date: 2026/3/19 16:06
* @Modified By:
*/
@Slf4j
public abstract class AbstractProtocolDriver<T> implements DriverCustomService {
protected Map<String, T> connectMap = new ConcurrentHashMap<>();;
// 注入映射管理器
protected final ConnectionProtocolMappingManager mappingManager;
// 构造方法注入
public AbstractProtocolDriver(ConnectionProtocolMappingManager mappingManager) {
this.mappingManager = mappingManager;
}
/**
* 创建连接(统一方法,自动注册映射)
* @param connectionId 连接ID原key
* @param protocolCode 协议编码
* @param connection 连接对象
*/
public void addConnection(String connectionId, String protocolCode, T connection) {
if (connection == null) {
throw new CommonException("连接对象不能为空");
}
connectMap.put(connectionId, connection);
// 注册连接ID与协议的映射
mappingManager.registerMapping(connectionId, protocolCode);
log.info("新增连接:协议={}连接ID={}", protocolCode, connectionId);
}
/**
* 重写删除方法:删除连接后同步清理映射
*/
public void removeConnection(String connectionId) {
if (connectMap.isEmpty() || !connectMap.containsKey(connectionId)) {
log.warn("连接ID={}不存在,无需删除", connectionId);
return;
}
// 1. 删除连接对象
T connection = connectMap.remove(connectionId);
closeConnection(connection);
// 2. 清理映射关系
mappingManager.removeMapping(connectionId);
log.info("删除连接成功连接ID={}", connectionId);
}
/**
* 抽象方法:子类实现具体的连接关闭逻辑(类型安全)
* @param connection 要关闭的连接对象
*/
protected abstract void closeConnection(T connection);
// 保留event方法的抽象子类必须实现
// @Override
// public abstract void event(MetadataEventDTO metadataEvent);
}

View File

@@ -0,0 +1,72 @@
package org.nl.iot.core.driver;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.exception.CommonException;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 全局连接ID-协议编码映射管理器
* 核心作用记录每个连接ID所属的协议编码解决删除时"只知ID不知协议"的问题
* @Author: liyongde
* @Date: 2026/3/19 16:30
* @Modified By:
*/
@Slf4j
@Component
public class ConnectionProtocolMappingManager {
/**
* 映射表连接ID → 协议编码(如 "conn_123" → "MODBUS"
*/
private final Map<String, String> connectionId2ProtocolCode = new ConcurrentHashMap<>();
/**
* 注册连接ID与协议编码的映射创建连接时调用
*/
public void registerMapping(String connectionId, String protocolCode) {
if (connectionId == null || connectionId.trim().isEmpty()) {
throw new CommonException("连接ID不能为空");
}
if (protocolCode == null || protocolCode.trim().isEmpty()) {
throw new CommonException("协议编码不能为空");
}
String upperCode = protocolCode.trim().toUpperCase();
connectionId2ProtocolCode.put(connectionId.trim(), upperCode);
log.debug("注册连接映射连接ID={} → 协议编码={}", connectionId, upperCode);
}
/**
* 根据连接ID获取协议编码删除连接时调用
*/
public String getProtocolCodeByConnectionId(String connectionId) {
if (connectionId == null || connectionId.trim().isEmpty()) {
throw new CommonException("连接ID不能为空");
}
String protocolCode = connectionId2ProtocolCode.get(connectionId.trim());
if (protocolCode == null) {
throw new CommonException("未找到连接ID[" + connectionId + "]对应的协议编码");
}
return protocolCode;
}
/**
* 删除映射关系(连接删除后同步清理)
*/
public void removeMapping(String connectionId) {
if (connectionId == null) {
return;
}
connectionId2ProtocolCode.remove(connectionId.trim());
log.debug("移除连接映射连接ID={}", connectionId);
}
/**
* 检查连接ID是否已注册
*/
public boolean containsMapping(String connectionId) {
return connectionId != null && connectionId2ProtocolCode.containsKey(connectionId.trim());
}
}

View File

@@ -0,0 +1,45 @@
package org.nl.iot.core.driver;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.exception.CommonException;
import org.nl.iot.core.driver.service.DriverCustomService;
import org.springframework.stereotype.Component;
/**
*
* @Author: liyongde
* @Date: 2026/3/19 16:49
* @Modified By:
*/
@Slf4j
@Component
public class DriverConnectionManager {
@Resource
private DriverCustomFactory driverCustomFactory;
@Resource
private ConnectionProtocolMappingManager mappingManager;
/**
* 核心方法仅传入连接ID自动删除对应协议的连接
* (无需知道协议编码,完全适配你的场景)
*/
public void removeConnectionById(String connectionId) {
// 1. 校验参数
if (connectionId == null || connectionId.trim().isEmpty()) {
throw new CommonException("连接ID不能为空");
}
// 2. 根据连接ID获取协议编码
String protocolCode = mappingManager.getProtocolCodeByConnectionId(connectionId);
// 3. 通过工厂类获取对应驱动
DriverCustomService driver = driverCustomFactory.getDriver(protocolCode);
if (!(driver instanceof AbstractProtocolDriver<?>)) {
throw new CommonException("驱动类[" + driver.getClass().getSimpleName() + "]未继承AbstractProtocolDriver");
}
// 4. 强转并调用删除方法
AbstractProtocolDriver<?> abstractDriver = (AbstractProtocolDriver<?>) driver;
abstractDriver.removeConnection(connectionId);
log.info("删除连接完成连接ID={},协议编码={}", connectionId, protocolCode);
}
}

View File

@@ -1,6 +1,5 @@
package org.nl.iot.core.driver.protocol.modbustcp;
import jakarta.annotation.PostConstruct;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.plc4x.java.DefaultPlcDriverManager;
@@ -11,6 +10,8 @@ import org.apache.plc4x.java.api.messages.PlcWriteRequest;
import org.apache.plc4x.java.api.messages.PlcWriteResponse;
import org.apache.plc4x.java.api.types.PlcResponseCode;
import org.apache.plc4x.java.api.value.PlcValue;
import org.nl.iot.core.driver.AbstractProtocolDriver;
import org.nl.iot.core.driver.ConnectionProtocolMappingManager;
import org.nl.iot.core.driver.ProtocolDriver;
import org.nl.iot.core.driver.ProtocolType;
import org.nl.iot.core.driver.bo.DeviceBO;
@@ -19,16 +20,16 @@ import org.nl.iot.core.driver.bo.SiteBO;
import org.nl.iot.core.driver.entity.RValue;
import org.nl.iot.core.driver.entity.WResponse;
import org.nl.iot.core.driver.entity.WValue;
import org.nl.iot.core.driver.enums.MetadataOperateTypeEnum;
import org.nl.iot.core.driver.util.JavaToPlcValueConvertUtil;
import org.nl.iot.core.driver.protocol.modbustcp.util.ModBusTcpUtils;
import org.nl.iot.core.driver.util.JavaToPlcValueConvertUtil;
import org.nl.iot.core.driver.util.PlcValueConvertUtil;
import org.nl.iot.core.driver.service.DriverCustomService;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
@@ -39,14 +40,14 @@ import java.util.concurrent.TimeUnit;
@Slf4j
@Service
@ProtocolDriver(ProtocolType.MODBUS)
public class ModBusProtocolDriverImpl implements DriverCustomService {
public class ModBusProtocolDriverImpl extends AbstractProtocolDriver<PlcConnection> {
private Map<String, PlcConnection> connectMap;
public ModBusProtocolDriverImpl(ConnectionProtocolMappingManager mappingManager) {
super(mappingManager);
}
@Override
@PostConstruct
public void initial() {
connectMap = new ConcurrentHashMap<>(16);
}
@Override
@@ -56,13 +57,13 @@ public class ModBusProtocolDriverImpl implements DriverCustomService {
@Override
public void event(MetadataEventDTO metadataEvent) {
MetadataOperateTypeEnum operateType = metadataEvent.getOperateType();
log.info("Device metadata event: connectId: {}, operate: {}", metadataEvent.getConnectId(), operateType);
// When the device is updated or deleted, remove the corresponding connection handle
if (MetadataOperateTypeEnum.DELETE.equals(operateType) || MetadataOperateTypeEnum.UPDATE.equals(operateType)) {
connectMap.remove(metadataEvent.getConnectId());
}
// MetadataOperateTypeEnum operateType = metadataEvent.getOperateType();
// log.info("Device metadata event: connectId: {}, operate: {}", metadataEvent.getConnectId(), operateType);
//
// // When the device is updated or deleted, remove the corresponding connection handle
// if (MetadataOperateTypeEnum.DELETE.equals(operateType) || MetadataOperateTypeEnum.UPDATE.equals(operateType)) {
// connectMap.remove(metadataEvent.getConnectId());
// }
}
@Override
@@ -85,6 +86,14 @@ public class ModBusProtocolDriverImpl implements DriverCustomService {
return batchWriteValue(getConnector(device), wValue);
}
@Override
protected void closeConnection(PlcConnection connection) {
try {
connection.close();
} catch (Exception e) {
log.warn("关闭失败:{}", e.getMessage());
}
}
@SneakyThrows
public static List<WResponse> batchWriteValue(PlcConnection modbusMaster, List<WValue> wValues) {
List<WResponse> res = new ArrayList<>();
@@ -119,6 +128,7 @@ public class ModBusProtocolDriverImpl implements DriverCustomService {
try {
if (Objects.isNull(modbusMaster)) {
modbusMaster = new DefaultPlcDriverManager().getConnection(ModBusTcpUtils.buildModBusPlcUrl(deviceBO));
createModBusConnection(deviceBO.getId(), modbusMaster);
}
} catch (Exception e) {
throw new RuntimeException(e);
@@ -126,6 +136,12 @@ public class ModBusProtocolDriverImpl implements DriverCustomService {
return modbusMaster;
}
// 业务中创建连接时调用父类的addConnection方法
public void createModBusConnection(String connectionId, PlcConnection connection) {
// 传入协议编码MODBUS和连接ID、连接对象
addConnection(connectionId, ProtocolType.MODBUS.getMainCode(), connection);
}
@SneakyThrows
public String readValue(PlcConnection modbusMaster, SiteBO point) {
// 1. 解析配置

View File

@@ -2,12 +2,13 @@ package org.nl.iot.core.driver.protocol.opcda;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import jakarta.annotation.PostConstruct;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.core.JIVariant;
import org.nl.common.exception.CommonException;
import org.nl.iot.core.driver.AbstractProtocolDriver;
import org.nl.iot.core.driver.ConnectionProtocolMappingManager;
import org.nl.iot.core.driver.ProtocolDriver;
import org.nl.iot.core.driver.ProtocolType;
import org.nl.iot.core.driver.bo.DeviceBO;
@@ -16,14 +17,12 @@ import org.nl.iot.core.driver.bo.SiteBO;
import org.nl.iot.core.driver.entity.RValue;
import org.nl.iot.core.driver.entity.WResponse;
import org.nl.iot.core.driver.entity.WValue;
import org.nl.iot.core.driver.enums.MetadataOperateTypeEnum;
import org.nl.iot.core.driver.enums.PointTypeFlagEnum;
import org.nl.iot.core.driver.protocol.opcda.org.openscada.opc.lib.common.AlreadyConnectedException;
import org.nl.iot.core.driver.protocol.opcda.org.openscada.opc.lib.common.ConnectionInformation;
import org.nl.iot.core.driver.protocol.opcda.org.openscada.opc.lib.common.NotConnectedException;
import org.nl.iot.core.driver.protocol.opcda.org.openscada.opc.lib.da.*;
import org.nl.iot.core.driver.protocol.opcda.util.JIVariantToStringUtil;
import org.nl.iot.core.driver.service.DriverCustomService;
import org.springframework.stereotype.Service;
import java.net.UnknownHostException;
@@ -31,29 +30,19 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
@Slf4j
@Service
@ProtocolDriver(ProtocolType.OPCDA)
public class OpcDaProtocolDriverImpl implements DriverCustomService {
/**
* Opc Da Server Map
*/
private Map<String, Server> connectMap;
public class OpcDaProtocolDriverImpl extends AbstractProtocolDriver<Server> {
public OpcDaProtocolDriverImpl(ConnectionProtocolMappingManager mappingManager) {
super(mappingManager);
}
@PostConstruct
@Override
public void initial() {
/*
* 驱动初始化逻辑
*
* 提示: 此处逻辑仅供参考, 请务必结合实际应用场景进行修改。
* 驱动启动时会自动执行该方法, 您可以在此处执行特定的初始化操作。
*
*/
connectMap = new ConcurrentHashMap<>(16);
}
@Override
@@ -63,12 +52,21 @@ public class OpcDaProtocolDriverImpl implements DriverCustomService {
@Override
public void event(MetadataEventDTO metadataEvent) {
MetadataOperateTypeEnum operateType = metadataEvent.getOperateType();
log.info("Device metadata event: connectId: {}, operate: {}", metadataEvent.getConnectId(), operateType);
// MetadataOperateTypeEnum operateType = metadataEvent.getOperateType();
// log.info("Device metadata event: connectId: {}, operate: {}", metadataEvent.getConnectId(), operateType);
//
// // When the device is updated or deleted, remove the corresponding connection handle
// if (MetadataOperateTypeEnum.DELETE.equals(operateType) || MetadataOperateTypeEnum.UPDATE.equals(operateType)) {
// connectMap.remove(metadataEvent.getConnectId());
// }
}
// When the device is updated or deleted, remove the corresponding connection handle
if (MetadataOperateTypeEnum.DELETE.equals(operateType) || MetadataOperateTypeEnum.UPDATE.equals(operateType)) {
connectMap.remove(metadataEvent.getConnectId());
@Override
protected void closeConnection(Server server) {
try {
server.disconnect();
} catch (Exception e) {
log.warn("关闭失败:{}", e.getMessage());
}
}
@@ -109,9 +107,9 @@ public class OpcDaProtocolDriverImpl implements DriverCustomService {
server = new Server(connectionInformation, Executors.newSingleThreadScheduledExecutor());
try {
server.connect();
connectMap.put(deviceBO.getId(), server);
addOpcDaConnection(deviceBO.getId(), server);
} catch (AlreadyConnectedException | UnknownHostException | JIException e) {
connectMap.entrySet().removeIf(next -> next.getKey().equals(deviceBO.getId()));
removeConnection(deviceBO.getId());
log.error("Connect opc da server error: {}", e.getMessage(), e);
throw new CommonException(e.getMessage());
}
@@ -119,6 +117,12 @@ public class OpcDaProtocolDriverImpl implements DriverCustomService {
return server;
}
// 业务中创建连接时调用父类的addConnection方法
public void addOpcDaConnection(String connectionId, Server connection) {
// 传入协议编码OpcDa和连接ID、连接对象
addConnection(connectionId, ProtocolType.OPCDA.getMainCode(), connection);
}
/**
* 从 OPC DA 服务器读取位号值
* <p>

View File

@@ -1,11 +1,9 @@
package org.nl.iot.core.driver.protocol.opcua;
import com.alibaba.fastjson.JSONObject;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
import org.eclipse.milo.opcua.stack.core.AttributeId;
import org.eclipse.milo.opcua.stack.core.UaException;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
@@ -13,8 +11,9 @@ import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
import org.eclipse.milo.opcua.stack.core.types.structured.WriteValue;
import org.nl.common.exception.CommonException;
import org.nl.iot.core.driver.AbstractProtocolDriver;
import org.nl.iot.core.driver.ConnectionProtocolMappingManager;
import org.nl.iot.core.driver.ProtocolDriver;
import org.nl.iot.core.driver.ProtocolType;
import org.nl.iot.core.driver.bo.DeviceBO;
@@ -25,49 +24,38 @@ import org.nl.iot.core.driver.entity.WResponse;
import org.nl.iot.core.driver.entity.WValue;
import org.nl.iot.core.driver.enums.MetadataOperateTypeEnum;
import org.nl.iot.core.driver.enums.PointTypeFlagEnum;
import org.nl.iot.core.driver.service.DriverCustomService;
import org.springframework.stereotype.Service;
import jakarta.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@Slf4j
@Service
@ProtocolDriver(ProtocolType.OPCUA)
public class OpcUaProtocolDriverImpl implements DriverCustomService {
private Map<String, OpcUaClient> connectMap;
public class OpcUaProtocolDriverImpl extends AbstractProtocolDriver<OpcUaClient> {
@PostConstruct
@Override
public void initial() {
/*
* 驱动初始化逻辑
*
* 提示: 此处逻辑仅供参考, 请务必结合实际应用场景进行修改。
* 驱动启动时会自动执行该方法, 您可以在此处执行特定的初始化操作。
*
*/
connectMap = new ConcurrentHashMap<>(16);
public OpcUaProtocolDriverImpl(ConnectionProtocolMappingManager mappingManager) {
super(mappingManager);
}
// @PreDestroy
// public void destroy() {
// // 应用关闭时清理所有连接
// log.info("Cleaning up OPC UA connections...");
// connectMap.values().forEach(client -> {
// try {
// client.disconnect().get(5, TimeUnit.SECONDS);
// } catch (Exception e) {
// log.warn("Error disconnecting OPC UA client during cleanup: {}", e.getMessage());
// }
// });
// connectMap.clear();
// log.info("OPC UA connections cleanup completed");
// }
@Override
public void initial() {
}
@Override
protected void closeConnection(OpcUaClient client) {
try {
client.disconnect().get(5, TimeUnit.SECONDS);
} catch (Exception e) {
log.error("Error disconnecting OPC UA client during cleanup: {}", e.getMessage());
}
}
@Override
public void schedule() {
@@ -171,10 +159,10 @@ public class OpcUaProtocolDriverImpl implements DriverCustomService {
.setSessionTimeout(Unsigned.uint(60000)) // 设置会话超时时间为 60 秒
.build()
);
connectMap.put(device.getId(), opcUaClient);
addOPCUAConnection(device.getId(), opcUaClient);
log.info("Created new OPC UA client for device: {}", device.getId());
} catch (UaException e) {
connectMap.entrySet().removeIf(next -> next.getKey().equals(device.getId()));
removeConnection(device.getId());
log.error("Failed to create OPC UA client: {}", e.getMessage(), e);
throw new IllegalArgumentException(e.getMessage());
}
@@ -182,6 +170,12 @@ public class OpcUaProtocolDriverImpl implements DriverCustomService {
return opcUaClient;
}
// 业务中创建连接时调用父类的addConnection方法
public void addOPCUAConnection(String connectionId, OpcUaClient connection) {
// 传入协议编码OPCUA和连接ID、连接对象
addConnection(connectionId, ProtocolType.OPCUA.getMainCode(), connection);
}
/**
* 读取 OPC UA 节点的值
*

View File

@@ -1,6 +1,5 @@
package org.nl.iot.core.driver.protocol.plcs7;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.plc4x.java.DefaultPlcDriverManager;
import org.apache.plc4x.java.api.PlcConnection;
@@ -11,6 +10,8 @@ import org.apache.plc4x.java.api.messages.PlcWriteResponse;
import org.apache.plc4x.java.api.types.PlcResponseCode;
import org.apache.plc4x.java.api.value.PlcValue;
import org.nl.common.exception.CommonException;
import org.nl.iot.core.driver.AbstractProtocolDriver;
import org.nl.iot.core.driver.ConnectionProtocolMappingManager;
import org.nl.iot.core.driver.ProtocolDriver;
import org.nl.iot.core.driver.ProtocolType;
import org.nl.iot.core.driver.bo.DeviceBO;
@@ -19,15 +20,17 @@ import org.nl.iot.core.driver.bo.SiteBO;
import org.nl.iot.core.driver.entity.RValue;
import org.nl.iot.core.driver.entity.WResponse;
import org.nl.iot.core.driver.entity.WValue;
import org.nl.iot.core.driver.enums.MetadataOperateTypeEnum;
import org.nl.iot.core.driver.protocol.plcs7.util.PlcS7Utils;
import org.nl.iot.core.driver.util.JavaToPlcValueConvertUtil;
import org.nl.iot.core.driver.util.PlcValueConvertUtil;
import org.nl.iot.core.driver.protocol.plcs7.util.PlcS7Utils;
import org.nl.iot.core.driver.service.DriverCustomService;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
/**
*
@@ -37,18 +40,14 @@ import java.util.concurrent.*;
@Slf4j
@Service
@ProtocolDriver(ProtocolType.PLCS7)
public class PlcS7ProtocolDriverImpl implements DriverCustomService {
public class PlcS7ProtocolDriverImpl extends AbstractProtocolDriver<PlcConnection> {
/**
* Plc Connector Map
* 仅供参考
*/
private Map<String, PlcConnection> connectMap;
public PlcS7ProtocolDriverImpl(ConnectionProtocolMappingManager mappingManager) {
super(mappingManager);
}
@PostConstruct
@Override
public void initial() {
connectMap = new ConcurrentHashMap<>(16);
}
@Override
@@ -58,12 +57,21 @@ public class PlcS7ProtocolDriverImpl implements DriverCustomService {
@Override
public void event(MetadataEventDTO metadataEvent) {
MetadataOperateTypeEnum operateType = metadataEvent.getOperateType();
log.info("Device metadata event: connectId: {}, operate: {}", metadataEvent.getConnectId(), operateType);
// MetadataOperateTypeEnum operateType = metadataEvent.getOperateType();
// log.info("Device metadata event: connectId: {}, operate: {}", metadataEvent.getConnectId(), operateType);
//
// // When the device is updated or deleted, remove the corresponding connection handle
// if (MetadataOperateTypeEnum.DELETE.equals(operateType) || MetadataOperateTypeEnum.UPDATE.equals(operateType)) {
// connectMap.remove(metadataEvent.getConnectId());
// }
}
// When the device is updated or deleted, remove the corresponding connection handle
if (MetadataOperateTypeEnum.DELETE.equals(operateType) || MetadataOperateTypeEnum.UPDATE.equals(operateType)) {
connectMap.remove(metadataEvent.getConnectId());
@Override
protected void closeConnection(PlcConnection connection) {
try {
connection.close();
} catch (Exception e) {
log.warn("关闭失败:{}", e.getMessage());
}
}
@@ -145,7 +153,7 @@ public class PlcS7ProtocolDriverImpl implements DriverCustomService {
String connectionUrl = PlcS7Utils.getS7ConnectionUrl(deviceBO);
log.info("创建S7连接deviceId: {}, url: {}", deviceId, connectionUrl);
connection = new DefaultPlcDriverManager().getConnection(connectionUrl);
connectMap.put(deviceId, connection);
addPlcS7Connection(deviceBO.getId(), connection);
}
return connection;
} catch (Exception e) {
@@ -154,6 +162,12 @@ public class PlcS7ProtocolDriverImpl implements DriverCustomService {
}
}
// 业务中创建连接时调用父类的addConnection方法
public void addPlcS7Connection(String connectionId, PlcConnection connection) {
// 传入协议编码PLCS7和连接ID、连接对象
addConnection(connectionId, ProtocolType.PLCS7.getMainCode(), connection);
}
public static PlcReadRequest.Builder doBuildReadRequest(PlcConnection s7Connection, List<SiteBO> points) {
try {
PlcReadRequest.Builder readBuilder = s7Connection.readRequestBuilder();

View File

@@ -16,8 +16,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.pojo.CommonResult;
import org.nl.iot.core.driver.DriverConnectionManager;
import org.nl.iot.modular.iot.entity.IotConnect;
import org.nl.iot.modular.iot.entity.IotConfig;
import org.nl.iot.modular.iot.service.IotConfigService;
@@ -43,6 +45,8 @@ public class IotConnectController {
@Autowired
private IotConfigService iotConfigService;
@Resource
private DriverConnectionManager connectionManager;
/**
* 获取连接列表
@@ -92,6 +96,7 @@ public class IotConnectController {
@PostMapping("/edit")
public CommonResult edit(@RequestBody IotConnect connect) {
iotConnectService.updateById(connect);
connectionManager.removeConnectionById(connect.getId().toString());
return CommonResult.ok();
}
@@ -110,7 +115,7 @@ public class IotConnectController {
if (count > 0) {
throw new CommonException("连接已被信号配置使用,无法删除");
}
iotConnectService.removeById(connect.getId());
connectionManager.removeConnectionById(connect.getId().toString());
return CommonResult.ok();
}
@@ -128,6 +133,9 @@ public class IotConnectController {
throw new CommonException("所选连接存在信号配置,无法删除");
}
}
for (Integer id : ids) {
connectionManager.removeConnectionById(String.valueOf(id));
}
iotConnectService.removeBatchByIds(ids);
return CommonResult.ok();
}