mqtt修改

This commit is contained in:
小魔仙
2025-05-23 08:45:58 +08:00
parent 9d66ffc55b
commit 6646e6b5e5
5 changed files with 119 additions and 43 deletions

View File

@@ -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)
{