1111
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
using MQTTnet;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Protocol;
|
||||
|
||||
namespace Evergreen.Health.Application.Health.Integrations.Ib43;
|
||||
|
||||
public interface IIb43MqttTransport : IDisposable
|
||||
{
|
||||
bool IsConnected { get; }
|
||||
event Func<string, string, bool, Task> Message;
|
||||
event Action<string> OversizedMessage;
|
||||
Task ConnectAndSubscribeAsync(Ib43Options options, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
public interface IIb43MqttTransportFactory
|
||||
{
|
||||
IIb43MqttTransport Create();
|
||||
}
|
||||
|
||||
public sealed class Ib43MqttTransportFactory : IIb43MqttTransportFactory
|
||||
{
|
||||
public IIb43MqttTransport Create() => new Ib43MqttTransport();
|
||||
}
|
||||
|
||||
public sealed class Ib43MqttTransport : IIb43MqttTransport
|
||||
{
|
||||
private readonly IMqttClient _client = new MqttFactory().CreateMqttClient();
|
||||
public bool IsConnected => _client.IsConnected;
|
||||
public event Func<string, string, bool, Task> Message;
|
||||
public event Action<string> OversizedMessage;
|
||||
|
||||
public Ib43MqttTransport()
|
||||
{
|
||||
_client.ApplicationMessageReceivedAsync += async e =>
|
||||
{
|
||||
var m = e.ApplicationMessage;
|
||||
// 在解码前限制长度;不要将大包全部复制进诊断缓存。
|
||||
if (m.PayloadSegment.Count > Ib43StateStore.MaxPayloadBytes)
|
||||
OversizedMessage?.Invoke(m.Topic);
|
||||
else if (Message != null) await Message.Invoke(m.Topic, m.ConvertPayloadToString(), m.Retain);
|
||||
};
|
||||
}
|
||||
|
||||
public async Task ConnectAndSubscribeAsync(Ib43Options options, CancellationToken cancellationToken)
|
||||
{
|
||||
var builder = new MqttClientOptionsBuilder().WithTcpServer(options.Host, options.Port)
|
||||
.WithClientId(options.ClientId).WithCredentials(options.Username, options.Password)
|
||||
.WithProtocolVersion(MqttProtocolVersion.V311).WithCleanSession()
|
||||
.WithKeepAlivePeriod(TimeSpan.FromSeconds(30)).WithTimeout(TimeSpan.FromSeconds(10));
|
||||
if (options.UseTls) builder.WithTlsOptions(t => t.UseTls());
|
||||
await _client.ConnectAsync(builder.Build(), cancellationToken);
|
||||
var subscription = new MqttClientSubscribeOptionsBuilder();
|
||||
foreach (var device in options.Devices)
|
||||
subscription.WithTopicFilter(f => f.WithTopic(device.PostTopic)
|
||||
.WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce));
|
||||
var result = await _client.SubscribeAsync(subscription.Build(), cancellationToken);
|
||||
if (result.Items.Count != options.Devices.Count || result.Items.Any(i => (int)i.ResultCode >= 128))
|
||||
throw new InvalidOperationException("IB43 subscription rejected");
|
||||
}
|
||||
|
||||
public void Dispose() => _client.Dispose();
|
||||
}
|
||||
Reference in New Issue
Block a user