From c0223b083aa5014d2cad95644ef4afcec3056fc2 Mon Sep 17 00:00:00 2001 From: "David P.G" Date: Wed, 1 Oct 2025 18:28:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=9A=84=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=9A=20=20=20=201.=20=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=AF=B9?= =?UTF-8?q?=20EventService.OnDeviceChanged=20=E4=BA=8B=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E8=AE=A2=E9=98=85=20=20=20=202.=20=E5=AE=9E=E7=8E=B0=E4=BA=86?= =?UTF-8?q?=20OnDeviceChanged=20=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E6=A0=B9=E6=8D=AE=E5=8F=98=E5=8C=96?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=BF=9B=E8=A1=8C=E7=9B=B8=E5=BA=94=E5=A4=84?= =?UTF-8?q?=E7=90=86=20=20=20=203.=20=E5=AE=9E=E7=8E=B0=E4=BA=86=20HandleD?= =?UTF-8?q?eviceAdded=20=E6=96=B9=E6=B3=95=EF=BC=8C=E5=BD=93=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E6=B7=BB=E5=8A=A0=E6=97=B6=EF=BC=9A=20=20=20=20=20=20?= =?UTF-8?q?=20-=20=E6=A3=80=E6=9F=A5=E8=AE=BE=E5=A4=87=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E4=B8=BA=20OPC=20UA=20=20=20=20=20=20=20-=20?= =?UTF-8?q?=E5=B0=86=E8=AE=BE=E5=A4=87=E6=B7=BB=E5=8A=A0=E5=88=B0=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E5=88=97=E8=A1=A8=20=20=20=20=20=20=20-=20=E5=A6=82?= =?UTF-8?q?=E6=9E=9C=E8=AE=BE=E5=A4=87=E6=98=AF=E6=BF=80=E6=B4=BB=E7=8A=B6?= =?UTF-8?q?=E6=80=81=EF=BC=8C=E5=88=99=E8=87=AA=E5=8A=A8=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E8=AE=BE=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/OpcUa/OpcUaServiceManager.cs | 162 +++++++++++++++++- 1 file changed, 161 insertions(+), 1 deletion(-) diff --git a/DMS.Infrastructure/Services/OpcUa/OpcUaServiceManager.cs b/DMS.Infrastructure/Services/OpcUa/OpcUaServiceManager.cs index 8ee5325..8f5c22c 100644 --- a/DMS.Infrastructure/Services/OpcUa/OpcUaServiceManager.cs +++ b/DMS.Infrastructure/Services/OpcUa/OpcUaServiceManager.cs @@ -1,6 +1,7 @@ using System.Collections.Concurrent; using System.Diagnostics; using DMS.Application.DTOs; +using DMS.Application.Events; using DMS.Application.Interfaces; using DMS.Application.Models; using DMS.Core.Enums; @@ -10,7 +11,6 @@ using DMS.Infrastructure.Interfaces.Services; using DMS.Infrastructure.Models; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using VariableValueChangedEventArgs = DMS.Core.Events.VariableValueChangedEventArgs; namespace DMS.Infrastructure.Services.OpcUa { @@ -46,6 +46,7 @@ namespace DMS.Infrastructure.Services.OpcUa _semaphore = new SemaphoreSlim(_options.MaxConcurrentConnections, _options.MaxConcurrentConnections); _eventService.OnDeviceActiveChanged += OnDeviceActiveChanged; + _eventService.OnDeviceChanged += OnDeviceChanged; } private async void OnDeviceActiveChanged(object? sender, DeviceActiveChangedEventArgs e) @@ -60,6 +61,165 @@ namespace DMS.Infrastructure.Services.OpcUa } } + private void OnDeviceChanged(object? sender, DeviceChangedEventArgs e) + { + switch (e.ChangeType) + { + case DataChangeType.Added: + // 当设备被添加时,加载并连接该设备 + HandleDeviceAdded(e.Device); + break; + case DataChangeType.Updated: + // 当设备被更新时,更新其配置 + HandleDeviceUpdated(e.Device); + break; + case DataChangeType.Deleted: + // 当设备被删除时,移除设备监控 + HandleDeviceRemoved(e.Device.Id); + break; + } + } + + /// + /// 处理设备添加事件 + /// + private void HandleDeviceAdded(DeviceDto device) + { + if (device == null) + { + _logger.LogWarning("HandleDeviceAdded: 接收到空设备对象"); + return; + } + + // 检查设备协议是否为OPC UA + if (device.Protocol != Core.Enums.ProtocolType.OpcUa) + { + _logger.LogInformation("设备 {DeviceId} ({DeviceName}) 不是OPC UA协议,跳过加载", + device.Id, device.Name); + return; + } + + try + { + _logger.LogInformation("处理设备添加事件: {DeviceId} ({DeviceName})", + device.Id, device.Name); + + // 添加设备到监控列表 + AddDevice(device); + + // 如果设备是激活状态,则尝试连接 + if (device.IsActive) + { + // 使用Task.Run来避免阻塞事件处理 + _ = Task.Run(async () => + { + try + { + await ConnectDeviceAsync(device.Id, CancellationToken.None); + } + catch (Exception ex) + { + _logger.LogError(ex, "连接新添加的设备 {DeviceId} ({DeviceName}) 时发生错误", + device.Id, device.Name); + } + }); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "处理设备添加事件时发生错误: {DeviceId} ({DeviceName})", + device?.Id, device?.Name); + } + } + + /// + /// 处理设备更新事件 + /// + private void HandleDeviceUpdated(DeviceDto device) + { + if (device == null) + { + _logger.LogWarning("HandleDeviceUpdated: 接收到空设备对象"); + return; + } + + // 检查设备协议是否为OPC UA + if (device.Protocol != Core.Enums.ProtocolType.OpcUa) + { + _logger.LogInformation("设备 {DeviceId} ({DeviceName}) 不是OPC UA协议,跳过更新", + device.Id, device.Name); + return; + } + + try + { + _logger.LogInformation("处理设备更新事件: {DeviceId} ({DeviceName})", + device.Id, device.Name); + + // 先移除旧设备配置 + if (_deviceContexts.TryGetValue(device.Id, out var oldContext)) + { + // 断开旧连接 + _ = Task.Run(async () => + { + try + { + await DisconnectDeviceAsync(device.Id, CancellationToken.None); + } + catch (Exception ex) + { + _logger.LogError(ex, "断开旧设备 {DeviceId} ({DeviceName}) 连接时发生错误", + device.Id, device.Name); + } + }); + } + + // 添加更新后的设备 + AddDevice(device); + + // 如果设备是激活状态,则尝试连接 + if (device.IsActive) + { + // 使用Task.Run来避免阻塞事件处理 + _ = Task.Run(async () => + { + try + { + await ConnectDeviceAsync(device.Id, CancellationToken.None); + } + catch (Exception ex) + { + _logger.LogError(ex, "连接更新后的设备 {DeviceId} ({DeviceName}) 时发生错误", + device.Id, device.Name); + } + }); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "处理设备更新事件时发生错误: {DeviceId} ({DeviceName})", + device?.Id, device?.Name); + } + } + + /// + /// 处理设备删除事件 + /// + private async void HandleDeviceRemoved(int deviceId) + { + try + { + _logger.LogInformation("处理设备删除事件: {DeviceId}", deviceId); + + // 从监控列表中移除设备 + await RemoveDeviceAsync(deviceId, CancellationToken.None); + } + catch (Exception ex) + { + _logger.LogError(ex, "处理设备删除事件时发生错误: {DeviceId}", deviceId); + } + } + /// /// 初始化服务管理器 ///