完成S7变量启用和停用更新
This commit is contained in:
191
DMS.Infrastructure/Services/Mqtt/MqttService.cs
Normal file
191
DMS.Infrastructure/Services/Mqtt/MqttService.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using DMS.Infrastructure.Interfaces.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MQTTnet;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Client.Connecting;
|
||||
using MQTTnet.Client.Disconnecting;
|
||||
using MQTTnet.Client.Options;
|
||||
|
||||
namespace DMS.Infrastructure.Services.Mqtt
|
||||
{
|
||||
/// <summary>
|
||||
/// MQTT服务实现类,用于与MQTT服务器进行通信
|
||||
/// </summary>
|
||||
public class MqttService : IMqttService
|
||||
{
|
||||
private IMqttClient _mqttClient;
|
||||
private readonly ILogger<MqttService> _logger;
|
||||
private readonly IMqttClientOptions _options;
|
||||
private Func<string, string, Task> _messageHandler;
|
||||
private string _clientId;
|
||||
|
||||
public bool IsConnected => _mqttClient?.IsConnected ?? false;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,注入日志记录器
|
||||
/// </summary>
|
||||
/// <param name="logger">日志记录器实例</param>
|
||||
public MqttService(ILogger<MqttService> logger)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
var factory = new MqttFactory();
|
||||
_mqttClient = factory.CreateMqttClient();
|
||||
_clientId = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步连接到MQTT服务器
|
||||
/// </summary>
|
||||
public async Task ConnectAsync(string serverUrl, int port, string clientId, string username, string password)
|
||||
{
|
||||
try
|
||||
{
|
||||
_clientId = clientId ?? Guid.NewGuid().ToString();
|
||||
|
||||
var options = new MqttClientOptionsBuilder()
|
||||
.WithTcpServer(serverUrl, port)
|
||||
.WithClientId(_clientId)
|
||||
.WithCredentials(username, password)
|
||||
.WithCleanSession()
|
||||
.Build();
|
||||
|
||||
_mqttClient.UseConnectedHandler(async e => await HandleConnectedAsync(e));
|
||||
_mqttClient.UseDisconnectedHandler(async e => await HandleDisconnectedAsync(e));
|
||||
_mqttClient.UseApplicationMessageReceivedHandler(async e => await HandleMessageReceivedAsync(e));
|
||||
|
||||
await _mqttClient.ConnectAsync(options);
|
||||
_logger.LogInformation($"成功连接到MQTT服务器: {serverUrl}:{port} (ClientID: {_clientId})");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"连接MQTT服务器时发生错误: {ex.Message} (ClientID: {_clientId})");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步断开MQTT连接
|
||||
/// </summary>
|
||||
public async Task DisconnectAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_mqttClient != null && _mqttClient.IsConnected)
|
||||
{
|
||||
await _mqttClient.DisconnectAsync();
|
||||
_logger.LogInformation($"已断开MQTT服务器连接 (ClientID: {_clientId})");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"断开MQTT服务器连接时发生错误: {ex.Message} (ClientID: {_clientId})");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步发布消息
|
||||
/// </summary>
|
||||
public async Task PublishAsync(string topic, string payload)
|
||||
{
|
||||
if (!IsConnected)
|
||||
{
|
||||
throw new InvalidOperationException("MQTT客户端未连接");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var message = new MqttApplicationMessageBuilder()
|
||||
.WithTopic(topic)
|
||||
.WithPayload(payload ?? string.Empty)
|
||||
.WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce)
|
||||
.Build();
|
||||
|
||||
await _mqttClient.PublishAsync(message);
|
||||
_logger.LogDebug($"成功发布消息到主题 {topic} (ClientID: {_clientId})");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"发布消息到主题 {topic} 时发生错误: {ex.Message} (ClientID: {_clientId})");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步订阅主题
|
||||
/// </summary>
|
||||
public async Task SubscribeAsync(string topic)
|
||||
{
|
||||
if (!IsConnected)
|
||||
{
|
||||
throw new InvalidOperationException("MQTT客户端未连接");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _mqttClient.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic(topic).Build());
|
||||
_logger.LogInformation($"成功订阅主题: {topic} (ClientID: {_clientId})");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"订阅主题 {topic} 时发生错误: {ex.Message} (ClientID: {_clientId})");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置消息接收处理程序
|
||||
/// </summary>
|
||||
public void SetMessageHandler(Func<string, string, Task> handler)
|
||||
{
|
||||
_messageHandler = handler;
|
||||
}
|
||||
|
||||
#region 私有处理方法
|
||||
|
||||
private async Task HandleConnectedAsync(MqttClientConnectedEventArgs args)
|
||||
{
|
||||
_logger.LogInformation($"MQTT客户端连接成功 (ClientID: {_clientId})");
|
||||
}
|
||||
|
||||
private async Task HandleDisconnectedAsync(MqttClientDisconnectedEventArgs args)
|
||||
{
|
||||
_logger.LogWarning($"MQTT客户端断开连接: {args.Reason} (ClientID: {_clientId})");
|
||||
}
|
||||
|
||||
private async Task HandleMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs args)
|
||||
{
|
||||
var topic = args.ApplicationMessage.Topic;
|
||||
var payload = System.Text.Encoding.UTF8.GetString(args.ApplicationMessage.Payload);
|
||||
|
||||
_logger.LogDebug($"收到MQTT消息 - 主题: {topic}, 内容: {payload} (ClientID: {_clientId})");
|
||||
|
||||
if (_messageHandler != null)
|
||||
{
|
||||
await _messageHandler(topic, payload);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_mqttClient != null && _mqttClient.IsConnected)
|
||||
{
|
||||
_mqttClient.DisconnectAsync().Wait(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
_mqttClient?.Dispose();
|
||||
_logger.LogInformation($"MQTT服务资源已释放 (ClientID: {_clientId})");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"释放MQTT服务资源时发生错误: {ex.Message} (ClientID: {_clientId})");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user