Files
ThingsGateway/src/Plugin/ThingsGateway.Plugin.Mqtt/MqttCollect/MqttCollect.other.cs

189 lines
7.0 KiB
C#
Raw Normal View History

2025-01-24 22:42:26 +08:00
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://thingsgateway.cn/
// QQ群605534569
//------------------------------------------------------------------------------
using MQTTnet;
2025-10-18 23:14:55 +08:00
using PooledAwait;
2025-01-24 22:42:26 +08:00
#if NET6_0
using MQTTnet.Client;
#endif
using System.Text;
using ThingsGateway.Foundation;
using ThingsGateway.Gateway.Application.Extensions;
using ThingsGateway.NewLife;
2025-01-24 22:42:26 +08:00
using ThingsGateway.NewLife.Extension;
using ThingsGateway.NewLife.Json.Extension;
namespace ThingsGateway.Plugin.Mqtt;
/// <summary>
/// MqttClient
/// </summary>
public partial class MqttCollect : CollectBase
{
private IMqttClient _mqttClient;
private MqttClientOptions _mqttClientOptions;
private MqttClientSubscribeOptions _mqttSubscribeOptions;
2025-07-18 17:46:56 +08:00
private WaitLock ConnectLock = new(nameof(MqttCollect));
2025-01-24 22:42:26 +08:00
2025-08-12 16:00:53 +00:00
#if !Management
2025-01-24 22:42:26 +08:00
#region mqtt方法
private Task MqttClient_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs args)
{
#if NET8_0_OR_GREATER
var payload = args.ApplicationMessage.Payload;
var payloadCount = payload.Length;
#else
var payload = args.ApplicationMessage.PayloadSegment;
var payloadCount = payload.Count;
#endif
try
{
var tuples = TopicItemDict.FirstOrDefault(t => (MqttTopicFilterComparer.Compare(args.ApplicationMessage.Topic, t.Key) == MqttTopicFilterCompareResult.IsMatch)).Value;
if (tuples != null)
{
var payLoad = Encoding.UTF8.GetString(payload);
if (_driverPropertys.DetailLog)
{
if (LogMessage?.LogLevel <= TouchSocket.Core.LogLevel.Trace)
LogMessage?.LogTrace($"Topic{args.ApplicationMessage.Topic}{Environment.NewLine}PayLoad{payLoad}");
2025-01-24 22:42:26 +08:00
}
else
{
LogMessage?.LogTrace($"Topic{args.ApplicationMessage.Topic}");
2025-01-24 22:42:26 +08:00
}
Newtonsoft.Json.Linq.JToken json = Newtonsoft.Json.Linq.JToken.Parse(payLoad);
DateTime dateTime = DateTime.Now;
foreach (var item in tuples)
{
try
{
if (item.Item2.GetExpressionsResult(json).ToBoolean(true))
{
var jtoken = json.SelectToken(item.Item1);
object value;
if (jtoken is Newtonsoft.Json.Linq.JValue jValue)
{
value = jValue.Value;
}
else
{
value = jtoken;
}
item.Item3.SetValue(value, dateTime);
}
}
catch (Exception ex)
{
LogMessage?.LogTrace($"parse error: topic {Environment.NewLine}{args.ApplicationMessage.Topic} {Environment.NewLine} json {Environment.NewLine}{json} {Environment.NewLine} select: {item.Item1} {Environment.NewLine} {ex}");
2025-01-24 22:42:26 +08:00
}
}
}
}
catch (Exception ex)
{
LogMessage?.LogWarning($"parse error: topic {Environment.NewLine}{args.ApplicationMessage.Topic} {Environment.NewLine} {ex}");
2025-01-24 22:42:26 +08:00
}
return Task.CompletedTask;
}
private async Task MqttClient_ConnectedAsync(MqttClientConnectedEventArgs args)
{
//连接成功后订阅相关主题
if (_mqttSubscribeOptions != null)
{
var subResult = await _mqttClient.SubscribeAsync(_mqttSubscribeOptions).ConfigureAwait(false);
if (subResult.Items.Any(a => a.ResultCode > (MqttClientSubscribeResultCode)10))
{
LogMessage?.LogWarning($"Subscribe fail {subResult.Items
.Where(a => a.ResultCode > (MqttClientSubscribeResultCode)10)
.Select(a =>
new
{
Topic = a.TopicFilter.Topic,
ResultCode = a.ResultCode.ToString()
}
)
2025-05-20 23:21:58 +08:00
.ToSystemTextJsonString()}");
2025-01-24 22:42:26 +08:00
}
}
}
2025-10-18 23:14:55 +08:00
private ValueTask<OperResult> TryMqttClientAsync(CancellationToken cancellationToken)
2025-01-24 22:42:26 +08:00
{
2025-10-18 23:14:55 +08:00
if (DisposedValue || _mqttClient == null) return TouchSocket.Core.EasyValueTask.FromResult(new OperResult("MqttClient is disposed"));
2025-01-24 22:42:26 +08:00
if (_mqttClient?.IsConnected == true)
2025-10-18 23:14:55 +08:00
return TouchSocket.Core.EasyValueTask.FromResult(OperResult.Success);
return Client(this, cancellationToken);
2025-01-24 22:42:26 +08:00
2025-10-18 23:14:55 +08:00
static async PooledValueTask<OperResult> Client(MqttCollect @this, CancellationToken cancellationToken)
2025-01-24 22:42:26 +08:00
{
2025-10-18 23:14:55 +08:00
if (@this._mqttClient?.IsConnected == true)
2025-01-24 22:42:26 +08:00
return OperResult.Success;
try
{
2025-10-18 23:14:55 +08:00
await @this.ConnectLock.WaitAsync(cancellationToken).ConfigureAwait(false);
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
2025-10-18 23:14:55 +08:00
if (@this._mqttClient?.IsConnected == true)
2025-01-24 22:42:26 +08:00
return OperResult.Success;
2025-10-18 23:14:55 +08:00
using var timeoutToken = new CancellationTokenSource(TimeSpan.FromMilliseconds(@this._driverPropertys.ConnectTimeout));
2025-01-24 22:42:26 +08:00
using CancellationTokenSource stoppingToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutToken.Token);
2025-10-18 23:14:55 +08:00
if (@this._mqttClient?.IsConnected == true)
2025-01-24 22:42:26 +08:00
return OperResult.Success;
2025-10-18 23:14:55 +08:00
if (@this._mqttClient == null)
2025-01-24 22:42:26 +08:00
{
return new OperResult("mqttClient is null");
}
2025-10-18 23:14:55 +08:00
var result = await @this._mqttClient.ConnectAsync(@this._mqttClientOptions, stoppingToken.Token).ConfigureAwait(false);
if (@this._mqttClient.IsConnected)
2025-01-24 22:42:26 +08:00
{
return OperResult.Success;
}
else
{
if (timeoutToken.IsCancellationRequested)
return new OperResult($"Connect timeout");
else
return new OperResult($"Connect fail {result.ReasonString}");
}
}
catch (Exception ex)
{
return new OperResult(ex);
}
finally
{
2025-10-18 23:14:55 +08:00
@this.ConnectLock.Release();
2025-01-24 22:42:26 +08:00
}
}
}
#endregion mqtt方法
2025-08-12 16:00:53 +00:00
#endif
2025-01-24 22:42:26 +08:00
}