重构MQTT事件处理和激活状态管理功能

This commit is contained in:
2025-10-05 14:45:41 +08:00
parent b96101dea6
commit 80ea47e627
13 changed files with 70 additions and 198 deletions

View File

@@ -55,17 +55,6 @@ public interface IEventService
#region MQTT事件
/// <summary>
/// MQTT连接状态改变事件
/// </summary>
event EventHandler<MqttConnectionChangedEventArgs> MqttConnectionChanged;
/// <summary>
/// 触发MQTT连接状态改变事件
/// </summary>
/// <param name="sender">事件发送者</param>
/// <param name="e">MQTT连接状态改变事件参数</param>
void RaiseMqttConnectionChanged(object sender, MqttConnectionChangedEventArgs e);
/// <summary>
/// MQTT服务器改变事件
@@ -107,7 +96,6 @@ public interface IEventService
/// <param name="e">变量值改变事件参数</param>
void RaiseVariableChanged(object sender, VariableChangedEventArgs e);
void RaiseVariableActiveChanged(object sender,VariablesActiveChangedEventArgs e);
/// <summary>
/// 批量导入变量事件
@@ -121,11 +109,6 @@ public interface IEventService
/// <param name="e">批量导入变量事件参数</param>
void RaiseBatchImportVariables(object sender, BatchImportVariablesEventArgs e);
/// <summary>
/// 变量启停改变事件
/// </summary>
event EventHandler<VariablesActiveChangedEventArgs> OnVariableActiveChanged;
/// <summary>
/// 数据加载完成事件
/// </summary>

View File

@@ -29,6 +29,7 @@ public class MappingProfile : Profile
// MqttServer 映射
CreateMap<MqttServer, MqttServerDto>().ReverseMap();
CreateMap<MqttServerDto, MqttServerDto>().ReverseMap();
// VariableMqttAlias 映射
CreateMap<VariableMqttAlias, VariableMqttAliasDto>()

View File

@@ -85,15 +85,6 @@ public class EventService : IEventService
}
/// <summary>
/// 变量启停改变事件
/// </summary>
public event EventHandler<VariablesActiveChangedEventArgs> OnVariableActiveChanged;
public void RaiseVariableActiveChanged(object sender, VariablesActiveChangedEventArgs e)
{
OnVariableActiveChanged?.Invoke(sender, e);
}
/// <summary>
/// 批量导入变量事件
/// </summary>
@@ -128,22 +119,6 @@ public class EventService : IEventService
#endregion
#region MQTT事件
/// <summary>
/// MQTT连接状态改变事件
/// </summary>
public event EventHandler<MqttConnectionChangedEventArgs> MqttConnectionChanged;
/// <summary>
/// 触发MQTT连接状态改变事件
/// </summary>
/// <param name="sender">事件发送者</param>
/// <param name="e">MQTT连接状态改变事件参数</param>
public void RaiseMqttConnectionChanged(object sender, MqttConnectionChangedEventArgs e)
{
MqttConnectionChanged?.Invoke(sender, e);
}
/// <summary>
/// MQTT服务器改变事件
/// </summary>

View File

@@ -105,12 +105,6 @@ public class MqttManagementService : IMqttManagementService
this, new MqttServerChangedEventArgs(ActionChangeType.Updated, mMqttServerDto, property));
}
// 如果没有任何属性发生变化,至少触发一次更新事件
if (changedProperties.Count == 0)
{
_eventService.RaiseMqttServerChanged(
this, new MqttServerChangedEventArgs(ActionChangeType.Updated, mMqttServerDto, MqttServerPropertyType.All));
}
}
else
{

View File

@@ -1,48 +0,0 @@
namespace DMS.Core.Events;
/// <summary>
/// MQTT连接状态改变事件参数
/// </summary>
public class MqttConnectionChangedEventArgs : EventArgs
{
/// <summary>
/// MQTT服务器ID
/// </summary>
public int MqttServerId { get; }
/// <summary>
/// MQTT服务器名称
/// </summary>
public string MqttServerName { get; }
/// <summary>
/// 旧连接状态
/// </summary>
public bool OldConnectionStatus { get; }
/// <summary>
/// 新连接状态
/// </summary>
public bool NewConnectionStatus { get; }
/// <summary>
/// 状态改变时间
/// </summary>
public DateTime ChangeTime { get; }
/// <summary>
/// 初始化MqttConnectionChangedEventArgs类的新实例
/// </summary>
/// <param name="mqttServerId">MQTT服务器ID</param>
/// <param name="mqttServerName">MQTT服务器名称</param>
/// <param name="oldStatus">旧连接状态</param>
/// <param name="newStatus">新连接状态</param>
public MqttConnectionChangedEventArgs(int mqttServerId, string mqttServerName, bool oldStatus, bool newStatus)
{
MqttServerId = mqttServerId;
MqttServerName = mqttServerName;
OldConnectionStatus = oldStatus;
NewConnectionStatus = newStatus;
ChangeTime = DateTime.Now;
}
}

View File

@@ -1,20 +0,0 @@
namespace DMS.Core.Events;
public class VariablesActiveChangedEventArgs: EventArgs
{
public List<int> VariableIds { get; }
public int DeviceId{get;}
public bool NewStatus { get; }
public VariablesActiveChangedEventArgs(List<int> variableIds,int deviceId, bool newStatus)
{
VariableIds = variableIds;
DeviceId=deviceId;
NewStatus = newStatus;
}
}

View File

@@ -137,11 +137,11 @@ namespace DMS.Infrastructure.Services.Mqtt
try
{
while (!stoppingToken.IsCancellationRequested )
while (!stoppingToken.IsCancellationRequested)
{
await _reloadSemaphore.WaitAsync(stoppingToken);
if (stoppingToken.IsCancellationRequested ) break;
if (stoppingToken.IsCancellationRequested) break;
// 加载MQTT配置
if (!LoadMqttConfigurations())
@@ -155,7 +155,7 @@ namespace DMS.Infrastructure.Services.Mqtt
_logger.LogInformation("MQTT后台服务已启动");
// 保持运行状态
while (!stoppingToken.IsCancellationRequested && _reloadSemaphore.CurrentCount == 0)
while (!stoppingToken.IsCancellationRequested && _reloadSemaphore.CurrentCount == 0)
{
await Task.Delay(1000, stoppingToken);
}
@@ -186,9 +186,7 @@ namespace DMS.Infrastructure.Services.Mqtt
_mqttServers.Clear();
// 从数据服务中心获取所有激活的MQTT服务器
var mqttServerDtos = _appDataStorageService.MqttServers.Values
.Where(m => m.IsActive)
.ToList();
var mqttServerDtos = _appDataStorageService.MqttServers.Values.ToList();
foreach (var mqttServerDto in mqttServerDtos)
{

View File

@@ -49,11 +49,6 @@ namespace DMS.Infrastructure.Services.Mqtt
_eventService.OnMqttServerChanged += OnMqttServerChanged;
}
/// <summary>
/// 标志是否正在处理事件,用于防止递归调用
/// </summary>
private readonly ConcurrentDictionary<int, bool> _isProcessingUpdate = new();
/// <summary>
/// 初始化服务管理器
/// </summary>
@@ -81,10 +76,6 @@ namespace DMS.Infrastructure.Services.Mqtt
_mqttContexts.AddOrUpdate(mqttServer.Id, context, (key, oldValue) => context);
_logger.LogInformation("已添加MQTT服务器 {MqttServerId} 到监控列表", mqttServer.Id);
// 使用AutoMapper触发MQTT服务器改变事件
var mqttServerDto = _mapper.Map<MqttServerDto>(mqttServer);
_eventService.RaiseMqttServerChanged(this, new MqttServerChangedEventArgs(Core.Enums.ActionChangeType.Added, mqttServerDto));
}
/// <summary>
@@ -97,10 +88,6 @@ namespace DMS.Infrastructure.Services.Mqtt
await DisconnectMqttServerAsync(mqttServerId, cancellationToken);
_logger.LogInformation("已移除MQTT服务器 {MqttServerId} 的监控", mqttServerId);
// 使用AutoMapper触发MQTT服务器删除事件
var mqttServerDto = _mapper.Map<MqttServerDto>(context.MqttServerConfig);
_eventService.RaiseMqttServerChanged(this, new MqttServerChangedEventArgs(Core.Enums.ActionChangeType.Deleted, mqttServerDto));
}
}
@@ -352,14 +339,6 @@ namespace DMS.Infrastructure.Services.Mqtt
{
try
{
// 防止同一服务器的递归更新
if (_isProcessingUpdate.ContainsKey(e.MqttServer.Id) && _isProcessingUpdate[e.MqttServer.Id])
{
_logger.LogDebug("正在处理服务器 {MqttServerId} 的更新,跳过重复事件", e.MqttServer.Id);
return;
}
_isProcessingUpdate[e.MqttServer.Id] = true;
_logger.LogDebug("处理MQTT服务器变更事件: 服务器ID={MqttServerId}, 变更类型={ChangeType}, 变更属性={PropertyType}",
e.MqttServer.Id, e.ChangeType, e.PropertyType);
@@ -382,10 +361,6 @@ namespace DMS.Infrastructure.Services.Mqtt
_logger.LogError(ex, "处理MQTT服务器变更事件时发生错误: 服务器ID={MqttServerId}, 变更类型={ChangeType}",
e.MqttServer.Id, e.ChangeType);
}
finally
{
_isProcessingUpdate.TryRemove(e.MqttServer.Id, out _);
}
}
/// <summary>
@@ -474,10 +449,6 @@ namespace DMS.Infrastructure.Services.Mqtt
await ReconnectMqttServerAsync(mqttServer.Id, CancellationToken.None);
break;
case MqttServerPropertyType.IsActive:
// 检查当前激活状态和新激活状态是否一致
if (context.MqttServerConfig.IsActive != mqttServer.IsActive)
{
context.MqttServerConfig.IsActive = mqttServer.IsActive;
if (mqttServer.IsActive)
{
@@ -489,7 +460,6 @@ namespace DMS.Infrastructure.Services.Mqtt
// 激活状态变为false断开服务器连接
await DisconnectMqttServerAsync(mqttServer.Id, CancellationToken.None);
}
}
break;
case MqttServerPropertyType.SubscribeTopic:
context.MqttServerConfig.SubscribeTopic = mqttServer.SubscribeTopic;
@@ -557,9 +527,6 @@ namespace DMS.Infrastructure.Services.Mqtt
}
}
// 清理处理更新状态的字典
_isProcessingUpdate.Clear();
_logger.LogInformation("MQTT服务管理器已释放资源");
}
}

View File

@@ -45,33 +45,32 @@ namespace DMS.Infrastructure.Services.S7
_deviceContexts = new ConcurrentDictionary<int, S7DeviceContext>();
_semaphore = new SemaphoreSlim(10, 10); // 默认最大并发连接数为10
_eventService.OnVariableActiveChanged += OnVariableActiveChanged;
_eventService.OnBatchImportVariables += OnBatchImportVariables;
_eventService.OnVariableChanged += OnVariableChanged;
}
private void OnVariableActiveChanged(object? sender, VariablesActiveChangedEventArgs e)
{
if (_deviceContexts.TryGetValue(e.DeviceId, out var s7DeviceContext))
{
//private void OnVariableActiveChanged(object? sender, VariablesActiveChangedEventArgs e)
//{
// if (_deviceContexts.TryGetValue(e.DeviceId, out var s7DeviceContext))
// {
var variables = _appDataStorageService.Variables.Values.Where(v => e.VariableIds.Contains(v.Id))
.ToList();
foreach (var variable in variables)
{
if (e.NewStatus)
{
// 变量启用,从轮询列表中添加变量
s7DeviceContext.Variables.AddOrUpdate(variable.S7Address,variable, (key, oldValue) => variable);
}
else
{
// 变量停用,从轮询列表中移除变量
s7DeviceContext.Variables.Remove(variable.S7Address, out _);
}
}
}
}
// var variables = _appDataStorageService.Variables.Values.Where(v => e.VariableIds.Contains(v.Id))
// .ToList();
// foreach (var variable in variables)
// {
// if (e.NewStatus)
// {
// // 变量启用,从轮询列表中添加变量
// s7DeviceContext.Variables.AddOrUpdate(variable.S7Address,variable, (key, oldValue) => variable);
// }
// else
// {
// // 变量停用,从轮询列表中移除变量
// s7DeviceContext.Variables.Remove(variable.S7Address, out _);
// }
// }
// }
//}
/// <summary>
/// 初始化服务管理器

View File

@@ -82,7 +82,6 @@ public class DataEventService : IDataEventService
break;
case MqttServerPropertyType.IsConnect:
mqttServerItem.IsConnect=e.MqttServer.IsConnect;
_notificationService.ShowSuccess($"MQTT服务器{mqttServerItem.ServerName},连接发生了变化,状态:{e.MqttServer.IsConnect}");
break;
case MqttServerPropertyType.Username:
break;

View File

@@ -4,6 +4,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using DMS.Application.DTOs;
using DMS.Application.Interfaces;
using DMS.Application.Interfaces.Database;
using DMS.Application.Interfaces.Management;
using DMS.WPF.Interfaces;
using DMS.WPF.ViewModels.Items;
@@ -16,8 +17,8 @@ public class MqttDataService : IMqttDataService
{
private readonly IMapper _mapper;
private readonly IAppDataStorageService _appDataStorageService;
private readonly IMqttManagementService _mqttManagementService;
private readonly IDataStorageService _dataStorageService;
private readonly IMqttAppService _mqttAppService;
/// <summary>
@@ -25,12 +26,12 @@ public class MqttDataService : IMqttDataService
/// </summary>
/// <param name="mapper">AutoMapper 实例。</param>
/// <param name="mqttAppService">MQTT应用服务实例。</param>
public MqttDataService(IMapper mapper, IAppDataStorageService appDataStorageService, IDataStorageService dataStorageService, IMqttAppService mqttAppService)
public MqttDataService(IMapper mapper, IAppDataStorageService appDataStorageService,IMqttManagementService mqttManagementService, IDataStorageService dataStorageService)
{
_mapper = mapper;
_appDataStorageService = appDataStorageService;
_mqttManagementService = mqttManagementService;
_dataStorageService = dataStorageService;
_mqttAppService = mqttAppService;
}
/// <summary>
@@ -60,11 +61,8 @@ public class MqttDataService : IMqttDataService
/// </summary>
public async Task<MqttServerItemViewModel> AddMqttServer(MqttServerItemViewModel mqttServer)
{
var dto = _mapper.Map<MqttServerDto>(mqttServer);
var id = await _mqttAppService.CreateMqttServerAsync(dto);
dto.Id = id;
var mqttServerItem = _mapper.Map<MqttServerItemViewModel>(dto);
var mqttServerDto = await _mqttManagementService.CreateMqttServerAsync(_mapper.Map<MqttServerDto>(mqttServer));
var mqttServerItem = _mapper.Map<MqttServerItemViewModel>(mqttServerDto);
_dataStorageService.MqttServers.Add(mqttServerItem.Id,mqttServerItem);
return mqttServerItem;
@@ -76,7 +74,7 @@ public class MqttDataService : IMqttDataService
public async Task<bool> UpdateMqttServer(MqttServerItemViewModel mqttServer)
{
var dto = _mapper.Map<MqttServerDto>(mqttServer);
await _mqttAppService.UpdateMqttServerAsync(dto);
await _mqttManagementService.UpdateMqttServerAsync(dto);
return true;
}
@@ -85,7 +83,7 @@ public class MqttDataService : IMqttDataService
/// </summary>
public async Task<bool> DeleteMqttServer(MqttServerItemViewModel mqttServer)
{
await _mqttAppService.DeleteMqttServerAsync(mqttServer.Id);
await _mqttManagementService.DeleteMqttServerAsync(mqttServer.Id);
_dataStorageService.MqttServers.Remove(mqttServer.Id);
return true;
}

View File

@@ -64,12 +64,36 @@ public partial class MqttsViewModel : ViewModelBase
_navigationService = navigationService;
_notificationService = notificationService;
// Set static services for MqttServerItemViewModel
MqttServerItemViewModel.SetServices(_wpfDataService, _notificationService);
_mqttServeise = _dataStorageService.MqttServers.ToNotifyCollectionChanged(x=>x.Value);
}
[RelayCommand]
public async Task ToggleIsActive(MqttServerItemViewModel mqttServerItem)
{
try
{
if (mqttServerItem == null)
{
_notificationService.ShowError("没有选择任何MQTT服务器请选择后再点击切换激活状态");
return;
}
// 更新到数据存储
await _wpfDataService.MqttDataService.UpdateMqttServer(mqttServerItem);
// 显示操作结果
var statusText = mqttServerItem.IsActive ? "已启用" : "已停用";
_notificationService.ShowSuccess($"MQTT服务器 {mqttServerItem.ServerName} 已{statusText}");
}
catch (Exception e)
{
_logger.LogError(e, "切换MQTT服务器激活状态时发生错误");
_notificationService.ShowError($"切换MQTT服务器激活状态时发生错误{e.Message}", e);
}
}
/// <summary>
/// 添加MQTT服务器命令。
/// </summary>

View File

@@ -45,11 +45,13 @@
<!-- Row 0: Header with Name and ToggleSwitch -->
<DockPanel Grid.Row="0" Margin="0,0,0,10">
<ui:ToggleSwitch
<ToggleButton
DockPanel.Dock="Right"
IsOn="{Binding IsActive}"
OffContent="停止"
OnContent="启动" />
Command="{Binding DataContext.ToggleIsActiveCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
CommandParameter="{Binding }"
IsChecked="{Binding IsActive}"
Style="{StaticResource ToggleButtonSwitch}" />
<TextBlock
VerticalAlignment="Center"
FontSize="20"