Mqtt的是否启用修改后,保存到数据并连接Mqtt

This commit is contained in:
2025-07-08 12:52:33 +08:00
parent 3085bd0f3f
commit 103c7bf32e
4 changed files with 98 additions and 28 deletions

View File

@@ -1,11 +1,12 @@
using PMSWPF.Enums; using CommunityToolkit.Mvvm.ComponentModel;
using PMSWPF.Enums;
namespace PMSWPF.Models; namespace PMSWPF.Models;
/// <summary> /// <summary>
/// 表示MQTT配置信息。 /// 表示MQTT配置信息。
/// </summary> /// </summary>
public class Mqtt public partial class Mqtt : ObservableObject
{ {
/// <summary> /// <summary>
/// MQTT客户端ID。 /// MQTT客户端ID。
@@ -30,7 +31,8 @@ public class Mqtt
/// <summary> /// <summary>
/// 是否启用此MQTT配置。 /// 是否启用此MQTT配置。
/// </summary> /// </summary>
public bool IsActive { get; set; } [ObservableProperty]
private bool _isActive;
/// <summary> /// <summary>
/// 是否设置为默认MQTT客户端。 /// 是否设置为默认MQTT客户端。
@@ -81,4 +83,10 @@ public class Mqtt
/// 关联的变量数据列表。 /// 关联的变量数据列表。
/// </summary> /// </summary>
public List<VariableData>? VariableDatas { get; set; } public List<VariableData>? VariableDatas { get; set; }
/// <summary>
/// 是否连接。
/// </summary>
[ObservableProperty]
private bool _isConnected;
} }

View File

@@ -141,35 +141,42 @@ namespace PMSWPF.Services
private async Task LoadMqttConfigurations() private async Task LoadMqttConfigurations()
{ {
// 从数据服务获取所有MQTT配置。 // 从数据服务获取所有MQTT配置。
var mqtts = await _dataServices.GetMqttsAsync(); var allMqtts = await _dataServices.GetMqttsAsync();
foreach (var mqtt in mqtts) var activeMqtts = allMqtts.Where(m => m.IsActive).ToList();
var activeMqttIds = activeMqtts.Select(m => m.Id).ToHashSet();
// 断开并移除不再活跃或已删除的MQTT客户端。
var clientsToDisconnect = _mqttClients.Keys.Except(activeMqttIds).ToList();
foreach (var id in clientsToDisconnect)
{
if (_mqttClients.TryGetValue(id, out var client))
{
if (client.IsConnected)
{
await client.DisconnectAsync();
// 更新模型中的连接状态
if (_mqttConfigurations.TryGetValue(id, out var mqttConfig))
{
mqttConfig.IsConnected = false;
}
}
_mqttClients.Remove(id);
NlogHelper.Info($"Disconnected and removed MQTT client for ID: {id} (no longer active or removed).");
}
_mqttConfigurations.Remove(id);
_mqttVariableData.Remove(id);
}
// 连接或更新活跃的客户端。
foreach (var mqtt in activeMqtts)
{ {
// 如果客户端字典中不包含当前MQTT配置的客户端则尝试连接。
if (!_mqttClients.ContainsKey(mqtt.Id)) if (!_mqttClients.ContainsKey(mqtt.Id))
{ {
await ConnectMqttClient(mqtt); await ConnectMqttClient(mqtt);
} }
// 更新或添加MQTT配置到字典。 // 始终更新或添加MQTT配置到字典。
_mqttConfigurations[mqtt.Id] = mqtt; _mqttConfigurations[mqtt.Id] = mqtt;
} }
// 断开并移除不再配置中的MQTT客户端。
var removedMqttIds = _mqttClients.Keys.Except(mqtts.Select(m => m.Id)).ToList();
foreach (var id in removedMqttIds)
{
if (_mqttClients.ContainsKey(id))
{
var client = _mqttClients[id];
if (client.IsConnected)
{
await client.DisconnectAsync();
}
_mqttClients.Remove(id);
NlogHelper.Info($"Disconnected and removed MQTT client for ID: {id}");
}
_mqttConfigurations.Remove(id);
_mqttVariableData.Remove(id);
}
} }
/// <summary> /// <summary>
@@ -197,6 +204,7 @@ namespace PMSWPF.Services
{ {
NlogHelper.Info($"Connected to MQTT broker: {mqtt.Name}"); NlogHelper.Info($"Connected to MQTT broker: {mqtt.Name}");
NotificationHelper.ShowSuccess($"已连接到MQTT服务器: {mqtt.Name}"); NotificationHelper.ShowSuccess($"已连接到MQTT服务器: {mqtt.Name}");
mqtt.IsConnected = true;
}); });
// 设置断开连接事件处理程序。 // 设置断开连接事件处理程序。
@@ -204,6 +212,7 @@ namespace PMSWPF.Services
{ {
NlogHelper.Warn($"Disconnected from MQTT broker: {mqtt.Name}. Reason: {e.Reason}"); NlogHelper.Warn($"Disconnected from MQTT broker: {mqtt.Name}. Reason: {e.Reason}");
NotificationHelper.ShowInfo($"与MQTT服务器断开连接: {mqtt.Name}"); NotificationHelper.ShowInfo($"与MQTT服务器断开连接: {mqtt.Name}");
mqtt.IsConnected = false;
// 尝试重新连接。 // 尝试重新连接。
await Task.Delay(TimeSpan.FromSeconds(5)); // 等待5秒后重连 await Task.Delay(TimeSpan.FromSeconds(5)); // 等待5秒后重连
try try

View File

@@ -20,9 +20,33 @@ public partial class MqttsViewModel : ViewModelBase
private readonly ILogger<MqttsViewModel> _logger; private readonly ILogger<MqttsViewModel> _logger;
private readonly NavgatorServices _navgatorServices; private readonly NavgatorServices _navgatorServices;
[ObservableProperty]
private ObservableCollection<Mqtt> _mqtts; private ObservableCollection<Mqtt> _mqtts;
public ObservableCollection<Mqtt> Mqtts
{
get => _mqtts;
set
{
if (_mqtts != null)
{
foreach (var mqtt in _mqtts)
{
mqtt.PropertyChanged -= Mqtt_PropertyChanged;
}
}
SetProperty(ref _mqtts, value);
if (_mqtts != null)
{
foreach (var mqtt in _mqtts)
{
mqtt.PropertyChanged += Mqtt_PropertyChanged;
}
}
}
}
[ObservableProperty] [ObservableProperty]
private Mqtt _selectedMqtt; private Mqtt _selectedMqtt;
@@ -52,6 +76,26 @@ public partial class MqttsViewModel : ViewModelBase
}; };
} }
private async void Mqtt_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Mqtt.IsActive))
{
if (sender is Mqtt mqtt)
{
try
{
await _mqttRepository.Edit(mqtt);
NotificationHelper.ShowSuccess($"MQTT: {mqtt.Name} 的启用状态已更新。");
MessageHelper.SendLoadMessage(LoadTypes.Mqtts);
}
catch (Exception ex)
{
NotificationHelper.ShowError($"更新MQTT启用状态失败: {mqtt.Name} - {ex.Message}", ex);
}
}
}
}
[RelayCommand] [RelayCommand]
public async void AddMqtt() public async void AddMqtt()
{ {

View File

@@ -12,12 +12,21 @@
d:DesignWidth="300"> d:DesignWidth="300">
<UserControl.Resources> <UserControl.Resources>
<DataTemplate x:Key="MqttItemTemplate"> <DataTemplate x:Key="MqttItemTemplate">
<Border Background="{DynamicResource SystemControlBackgroundAltHighBrush}" <Border BorderBrush="{DynamicResource SystemControlHighlightBaseMediumLowBrush}"
BorderBrush="{DynamicResource SystemControlHighlightBaseMediumLowBrush}"
BorderThickness="1" BorderThickness="1"
CornerRadius="8" CornerRadius="8"
Margin="5" Margin="5"
Padding="15"> Padding="15">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAltHighBrush}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsConnected}" Value="True">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Border.Effect> <Border.Effect>
<DropShadowEffect ShadowDepth="1" <DropShadowEffect ShadowDepth="1"
Color="Black" Color="Black"