mqtt修改
This commit is contained in:
parent
9d66ffc55b
commit
6646e6b5e5
@ -5,6 +5,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Prism.Wpf" Version="8.1.97" />
|
||||
<PackageReference Include="System.Management" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\RIZO_Application.Models\RIZO_Application.Models.csproj" />
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using MQTTnet.Client;
|
||||
using Prism.Events;
|
||||
using Prism.Regions;
|
||||
@ -17,7 +18,7 @@ namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private MqttHelper? _mqttHelper;
|
||||
private SubscriptionToken _token;
|
||||
|
||||
|
||||
public MqttControlViewModel(
|
||||
IRegionManager regionManager,
|
||||
IEventAggregator eventAggregator)
|
||||
@ -40,7 +41,7 @@ namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
_mqttHelper = new MqttHelper(serverUrl, 1883, clientId);
|
||||
_mqttHelper.MessageReceived += HandleMqttMessage;
|
||||
_mqttHelper.ConnectionFailed += HandleMqttConnectionFailed;
|
||||
|
||||
_mqttHelper.Disconnected += Publish;
|
||||
if (await ConnectMqttAsync())
|
||||
{
|
||||
await SubscribeToTopicsAsync();
|
||||
@ -81,6 +82,7 @@ namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
{
|
||||
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"订阅:{printTopic}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async Task PublishInitialMessageAsync()
|
||||
@ -165,7 +167,14 @@ namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"发布扫描消息时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Publish(string message, int retries, int maxRetries)
|
||||
{
|
||||
_eventAggregator.GetEvent<SystemLogEvent>().Publish(message);
|
||||
if (retries>=maxRetries)
|
||||
{
|
||||
MessageBox.Show("MQTT已掉线,请停止扫码");
|
||||
}
|
||||
}
|
||||
public async void Destroy()
|
||||
{
|
||||
_token?.Dispose();
|
||||
|
||||
@ -5,11 +5,9 @@ using Prism.Events;
|
||||
using Prism.Regions;
|
||||
using RIZO_Application.Core;
|
||||
using RIZO_Application.Core.Mvvm;
|
||||
using RIZO_Helper.Tools;
|
||||
using RIZO_Application.Infrastructure.Model;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
{
|
||||
@ -19,7 +17,6 @@ namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
private readonly BartenderPrintHelper _printHelper;
|
||||
private SubscriptionToken _printEventToken;
|
||||
private bool _isDisposed;
|
||||
|
||||
public PrintControlViewModel(
|
||||
IRegionManager regionManager,
|
||||
IEventAggregator eventAggregator,
|
||||
@ -120,6 +117,10 @@ namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
subStringValues: Intersect,
|
||||
copies: 1);
|
||||
|
||||
//bool printSuccess = barTenderPrinter.PrintLabel(templatePath: printDto.Path,
|
||||
// subStringValues: Intersect,
|
||||
// copies: 1);
|
||||
|
||||
if (printSuccess)
|
||||
{
|
||||
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"打印成功: {printDto.Name}");
|
||||
|
||||
@ -10,6 +10,7 @@ using RIZO_Helper.Tools;
|
||||
using System.Windows;
|
||||
using System.IO.Ports;
|
||||
using System.Windows.Documents;
|
||||
using System.Management;
|
||||
|
||||
namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
{
|
||||
@ -21,6 +22,8 @@ namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
private bool _isConnected;
|
||||
private string _lastLabel;
|
||||
private DateTime _lastScanTime;
|
||||
private ManagementEventWatcher watcher= new ManagementEventWatcher(new WqlEventQuery(
|
||||
"SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2 OR EventType = 3"));
|
||||
// 串口连接状态属性
|
||||
public bool IsConnected
|
||||
{
|
||||
@ -52,11 +55,44 @@ namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
: base(regionManager)
|
||||
{
|
||||
|
||||
watcher.EventArrived += new EventArrivedEventHandler(DeviceChanged);
|
||||
watcher.Start();
|
||||
|
||||
_eventAggregator = eventAggregator;
|
||||
IsConnected = false; // 初始状态为未连接
|
||||
InitializeScanHelperAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void DeviceChanged(object sender, EventArrivedEventArgs e)
|
||||
{
|
||||
// 1. 获取设备变化前的端口列表
|
||||
string[] portsBefore = SerialPort.GetPortNames();
|
||||
|
||||
// 2. 等待系统完成端口更新(重要!)
|
||||
System.Threading.Thread.Sleep(500);
|
||||
|
||||
// 3. 获取设备变化后的端口列表
|
||||
string[] portsAfter = SerialPort.GetPortNames();
|
||||
|
||||
// 4. 检测新增的端口
|
||||
foreach (string port in portsAfter)
|
||||
{
|
||||
if (Array.IndexOf(portsBefore, port) == -1)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 检测移除的端口
|
||||
foreach (string port in portsBefore)
|
||||
{
|
||||
if (Array.IndexOf(portsAfter, port) == -1)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InitializeScanHelperAsync()
|
||||
{
|
||||
try
|
||||
@ -69,18 +105,17 @@ namespace RIZO_Application.Modules.ModuleName.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public async Task StartComScan()
|
||||
public async Task StartComScan(string comName = "COM1",int baudRate = 9600)
|
||||
{
|
||||
if (_isDisposed)
|
||||
throw new ObjectDisposedException(nameof(ScanControlViewModel));
|
||||
|
||||
string comName = "COM1";
|
||||
int baudRate = 9600;
|
||||
if (SerialConfigs.Current != null)
|
||||
{
|
||||
comName = SerialConfigs.Current.ComName ?? string.Empty;
|
||||
baudRate = SerialConfigs.Current.BaudRate ?? 9600;
|
||||
}
|
||||
|
||||
//if (SerialConfigs.Current != null)
|
||||
//{
|
||||
// comName = SerialConfigs.Current.ComName ?? string.Empty;
|
||||
// baudRate = SerialConfigs.Current.BaudRate ?? 9600;
|
||||
//}
|
||||
|
||||
_eventAggregator.GetEvent<SystemLogEvent>().Publish($"串口扫码枪初始化……串口:{comName} 波特率:{baudRate}");
|
||||
|
||||
|
||||
@ -13,12 +13,18 @@ namespace RIZO_Helper.Tools
|
||||
private readonly IMqttClient _mqttClient;
|
||||
private MqttClientOptions _options;
|
||||
private bool _isDisposed;
|
||||
private readonly SemaphoreSlim _connectionLock = new SemaphoreSlim(1, 1);
|
||||
|
||||
// 用于确保只有一个后台重连任务运行
|
||||
private bool _isReconnecting;
|
||||
private readonly object _reconnectLock = new object();
|
||||
|
||||
// 定义消息接收事件
|
||||
public event EventHandler<MqttApplicationMessageReceivedEventArgs>? MessageReceived;
|
||||
public event EventHandler<Exception>? ConnectionFailed;
|
||||
|
||||
public Action<string, int, int> Disconnected;
|
||||
|
||||
|
||||
public MqttHelper(string server, int port = 1883, string clientId = "wpf-demo", bool cleanSession = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(server))
|
||||
@ -37,8 +43,9 @@ namespace RIZO_Helper.Tools
|
||||
|
||||
_mqttClient.DisconnectedAsync += async e =>
|
||||
{
|
||||
Disconnected.Invoke($"MQTT连接断开,原因: {e.Reason}", 0, 1);
|
||||
Debug.WriteLine($"MQTT连接断开,原因: {e.Reason}");
|
||||
await ReconnectWithBackoffAsync();
|
||||
await StartReconnectIfNeededAsync();
|
||||
};
|
||||
|
||||
_mqttClient.ApplicationMessageReceivedAsync += e =>
|
||||
@ -58,35 +65,28 @@ namespace RIZO_Helper.Tools
|
||||
if (_mqttClient.IsConnected)
|
||||
return true;
|
||||
|
||||
await _connectionLock.WaitAsync(cancellationToken);
|
||||
Debug.WriteLine($"正在连接MQTT服务器: {_options.ChannelOptions}");
|
||||
|
||||
try
|
||||
{
|
||||
if (_mqttClient.IsConnected)
|
||||
return true;
|
||||
|
||||
Debug.WriteLine($"正在连接MQTT服务器: {_options.ChannelOptions}");
|
||||
|
||||
try
|
||||
{
|
||||
await _mqttClient.ConnectAsync(_options, cancellationToken);
|
||||
Debug.WriteLine("MQTT连接成功");
|
||||
return true;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Debug.WriteLine("MQTT连接操作被取消");
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"MQTT连接失败: {ex.Message}");
|
||||
ConnectionFailed?.Invoke(this, ex);
|
||||
return false;
|
||||
}
|
||||
await _mqttClient.ConnectAsync(_options, cancellationToken);
|
||||
Debug.WriteLine("MQTT连接成功");
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
_connectionLock.Release();
|
||||
Debug.WriteLine("MQTT连接操作被取消");
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"MQTT连接失败: {ex.Message}");
|
||||
ConnectionFailed?.Invoke(this, ex);
|
||||
|
||||
// 连接失败时启动重连
|
||||
await StartReconnectIfNeededAsync();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,6 +187,35 @@ namespace RIZO_Helper.Tools
|
||||
}
|
||||
}
|
||||
|
||||
// 启动重连任务(如果没有正在运行的重连任务)
|
||||
private async Task StartReconnectIfNeededAsync()
|
||||
{
|
||||
if (_isDisposed)
|
||||
return;
|
||||
|
||||
// 使用锁确保只有一个重连任务启动
|
||||
lock (_reconnectLock)
|
||||
{
|
||||
if (_isReconnecting)
|
||||
return;
|
||||
|
||||
_isReconnecting = true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await ReconnectWithBackoffAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 无论重连成功或失败,都标记为重连已完成
|
||||
lock (_reconnectLock)
|
||||
{
|
||||
_isReconnecting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ReconnectWithBackoffAsync()
|
||||
{
|
||||
if (_isDisposed)
|
||||
@ -198,7 +227,9 @@ namespace RIZO_Helper.Tools
|
||||
|
||||
while (retries < maxRetries && !_isDisposed)
|
||||
{
|
||||
// 指数退避算法,避免频繁重试
|
||||
int delayMs = baseDelayMs * (int)Math.Pow(2, retries);
|
||||
Disconnected.Invoke($"将在 {delayMs}ms 后尝试重新连接MQTT服务器 (尝试 {retries + 1}/{maxRetries})", retries+1, maxRetries);
|
||||
Debug.WriteLine($"将在 {delayMs}ms 后尝试重新连接MQTT服务器 (尝试 {retries + 1}/{maxRetries})");
|
||||
await Task.Delay(delayMs);
|
||||
|
||||
@ -242,7 +273,7 @@ namespace RIZO_Helper.Tools
|
||||
try
|
||||
{
|
||||
// 先取消事件订阅,防止在释放过程中触发事件
|
||||
_mqttClient.DisconnectedAsync -= async e => await ReconnectWithBackoffAsync();
|
||||
_mqttClient.DisconnectedAsync -= async e => await StartReconnectIfNeededAsync();
|
||||
_mqttClient.ApplicationMessageReceivedAsync -= e =>
|
||||
{
|
||||
MessageReceived?.Invoke(this, e);
|
||||
@ -255,7 +286,6 @@ namespace RIZO_Helper.Tools
|
||||
|
||||
// 释放资源
|
||||
_mqttClient.Dispose();
|
||||
_connectionLock.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user