mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-19 11:03:07 +08:00
Merge from develop.
This commit is contained in:
@@ -154,6 +154,9 @@ namespace MQTTnet.Adapter
|
||||
|
||||
return packet;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (IsWrappedException(exception))
|
||||
@@ -241,7 +244,8 @@ namespace MQTTnet.Adapter
|
||||
{
|
||||
if (exception is IOException && exception.InnerException is SocketException socketException)
|
||||
{
|
||||
if (socketException.SocketErrorCode == SocketError.ConnectionAborted)
|
||||
if (socketException.SocketErrorCode == SocketError.ConnectionAborted ||
|
||||
socketException.SocketErrorCode == SocketError.OperationAborted)
|
||||
{
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
|
||||
@@ -7,5 +7,9 @@ namespace MQTTnet.Client
|
||||
IMqttClient CreateMqttClient();
|
||||
|
||||
IMqttClient CreateMqttClient(IMqttNetLogger logger);
|
||||
|
||||
IMqttClient CreateMqttClient(IMqttClientAdapterFactory adapterFactory);
|
||||
|
||||
IMqttClient CreateMqttClient(IMqttNetLogger logger, IMqttClientAdapterFactory adapterFactory);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace MQTTnet.Client
|
||||
internal Task _keepAliveMessageSenderTask;
|
||||
private IMqttChannelAdapter _adapter;
|
||||
private bool _cleanDisconnectInitiated;
|
||||
private TaskCompletionSource<bool> _disconnectReason;
|
||||
private long _disconnectGate;
|
||||
|
||||
public MqttClient(IMqttClientAdapterFactory channelFactory, IMqttNetLogger logger)
|
||||
{
|
||||
@@ -55,12 +55,12 @@ namespace MQTTnet.Client
|
||||
|
||||
try
|
||||
{
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
_disconnectReason = new TaskCompletionSource<bool>();
|
||||
_options = options;
|
||||
_packetIdentifierProvider.Reset();
|
||||
_packetDispatcher.Reset();
|
||||
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
_disconnectGate = 0;
|
||||
_adapter = _adapterFactory.CreateClientAdapter(options, _logger);
|
||||
|
||||
_logger.Verbose($"Trying to connect with server ({_options.ChannelOptions}).");
|
||||
@@ -88,10 +88,12 @@ namespace MQTTnet.Client
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Error(exception, "Error while connecting with server.");
|
||||
if (_disconnectReason.TrySetException(exception))
|
||||
|
||||
if (!DisconnectIsPending())
|
||||
{
|
||||
await DisconnectInternalAsync(null, exception).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -109,7 +111,7 @@ namespace MQTTnet.Client
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_disconnectReason.TrySetCanceled())
|
||||
if (!DisconnectIsPending())
|
||||
{
|
||||
await DisconnectInternalAsync(null, null).ConfigureAwait(false);
|
||||
}
|
||||
@@ -184,10 +186,12 @@ namespace MQTTnet.Client
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_cancellationTokenSource?.Cancel(false);
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
|
||||
_adapter?.Dispose();
|
||||
_adapter = null;
|
||||
}
|
||||
|
||||
private async Task<MqttV3ConnAckPacket> AuthenticateAsync(MqttApplicationMessage willApplicationMessage, CancellationToken cancellationToken)
|
||||
@@ -213,7 +217,7 @@ namespace MQTTnet.Client
|
||||
|
||||
private void ThrowIfNotConnected()
|
||||
{
|
||||
if (!IsConnected) throw new MqttCommunicationException("The client is not connected.");
|
||||
if (!IsConnected || Interlocked.Read(ref _disconnectGate) == 1) throw new MqttCommunicationException("The client is not connected.");
|
||||
}
|
||||
|
||||
private void ThrowIfConnected(string message)
|
||||
@@ -223,9 +227,10 @@ namespace MQTTnet.Client
|
||||
|
||||
private async Task DisconnectInternalAsync(Task sender, Exception exception)
|
||||
{
|
||||
InitiateDisconnect();
|
||||
|
||||
var clientWasConnected = IsConnected;
|
||||
|
||||
InitiateDisconnect();
|
||||
|
||||
IsConnected = false;
|
||||
|
||||
try
|
||||
@@ -246,10 +251,7 @@ namespace MQTTnet.Client
|
||||
}
|
||||
finally
|
||||
{
|
||||
_adapter?.Dispose();
|
||||
_adapter = null;
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
Dispose();
|
||||
_cleanDisconnectInitiated = false;
|
||||
|
||||
_logger.Info("Disconnected.");
|
||||
@@ -263,16 +265,16 @@ namespace MQTTnet.Client
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_cancellationTokenSource == null || _cancellationTokenSource.IsCancellationRequested)
|
||||
if (_cancellationTokenSource?.IsCancellationRequested == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_cancellationTokenSource.Cancel(false);
|
||||
_cancellationTokenSource?.Cancel(false);
|
||||
}
|
||||
catch (Exception adapterException)
|
||||
catch (Exception exception)
|
||||
{
|
||||
_logger.Warning(adapterException, "Error while initiating disconnect.");
|
||||
_logger.Warning(exception, "Error while initiating disconnect.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -360,7 +362,7 @@ namespace MQTTnet.Client
|
||||
_logger.Error(exception, "Unhandled exception while sending/receiving keep alive packets.");
|
||||
}
|
||||
|
||||
if (_disconnectReason.TrySetException(exception))
|
||||
if (!DisconnectIsPending())
|
||||
{
|
||||
await DisconnectInternalAsync(_keepAliveMessageSenderTask, exception).ConfigureAwait(false);
|
||||
}
|
||||
@@ -379,8 +381,10 @@ namespace MQTTnet.Client
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
var packet = await _adapter.ReceivePacketAsync(TimeSpan.Zero, cancellationToken).ConfigureAwait(false);
|
||||
if (packet != null)
|
||||
var packet = await _adapter.ReceivePacketAsync(TimeSpan.Zero, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (packet != null && !cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
await ProcessReceivedPacketAsync(packet, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
@@ -407,7 +411,7 @@ namespace MQTTnet.Client
|
||||
|
||||
_packetDispatcher.Dispatch(exception);
|
||||
|
||||
if (_disconnectReason.TrySetException(exception))
|
||||
if (!DisconnectIsPending())
|
||||
{
|
||||
await DisconnectInternalAsync(_packetReceiverTask, exception).ConfigureAwait(false);
|
||||
}
|
||||
@@ -493,16 +497,20 @@ namespace MQTTnet.Client
|
||||
|
||||
private void StartReceivingPackets(CancellationToken cancellationToken)
|
||||
{
|
||||
_packetReceiverTask = Task.Run(
|
||||
_packetReceiverTask = Task.Factory.StartNew(
|
||||
() => ReceivePacketsAsync(cancellationToken),
|
||||
cancellationToken);
|
||||
cancellationToken,
|
||||
TaskCreationOptions.LongRunning,
|
||||
TaskScheduler.Default);
|
||||
}
|
||||
|
||||
private void StartSendingKeepAliveMessages(CancellationToken cancellationToken)
|
||||
{
|
||||
_keepAliveMessageSenderTask = Task.Run(
|
||||
_keepAliveMessageSenderTask = Task.Factory.StartNew(
|
||||
() => SendKeepAliveMessagesAsync(cancellationToken),
|
||||
cancellationToken);
|
||||
cancellationToken,
|
||||
TaskCreationOptions.LongRunning,
|
||||
TaskScheduler.Default);
|
||||
}
|
||||
|
||||
private void FireApplicationMessageReceivedEvent(MqttPublishPacket publishPacket)
|
||||
@@ -538,5 +546,10 @@ namespace MQTTnet.Client
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private bool DisconnectIsPending()
|
||||
{
|
||||
return Interlocked.CompareExchange(ref _disconnectGate, 1, 0) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace MQTTnet.Implementations
|
||||
return true;
|
||||
}
|
||||
|
||||
if (chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.RevocationStatusUnknown || c.Status == X509ChainStatusFlags.Revoked || c.Status == X509ChainStatusFlags.RevocationStatusUnknown))
|
||||
if (chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.RevocationStatusUnknown || c.Status == X509ChainStatusFlags.Revoked || c.Status == X509ChainStatusFlags.OfflineRevocation))
|
||||
{
|
||||
if (!_options.TlsOptions.IgnoreCertificateRevocationErrors)
|
||||
{
|
||||
|
||||
@@ -20,8 +20,8 @@ namespace MQTTnet.Implementations
|
||||
private readonly CancellationToken _cancellationToken;
|
||||
private readonly AddressFamily _addressFamily;
|
||||
private readonly MqttServerTcpEndpointBaseOptions _options;
|
||||
private readonly MqttServerTlsTcpEndpointOptions _tlsOptions;
|
||||
private readonly X509Certificate2 _tlsCertificate;
|
||||
|
||||
private Socket _socket;
|
||||
|
||||
public MqttTcpServerListener(
|
||||
@@ -36,6 +36,11 @@ namespace MQTTnet.Implementations
|
||||
_tlsCertificate = tlsCertificate;
|
||||
_cancellationToken = cancellationToken;
|
||||
_logger = logger.CreateChildLogger(nameof(MqttTcpServerListener));
|
||||
|
||||
if (_options is MqttServerTlsTcpEndpointOptions tlsOptions)
|
||||
{
|
||||
_tlsOptions = tlsOptions;
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<MqttServerAdapterClientAcceptedEventArgs> ClientAccepted;
|
||||
@@ -75,7 +80,7 @@ namespace MQTTnet.Implementations
|
||||
if (_tlsCertificate != null)
|
||||
{
|
||||
sslStream = new SslStream(new NetworkStream(clientSocket), false);
|
||||
await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, SslProtocols.Tls12, false).ConfigureAwait(false);
|
||||
await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, _tlsOptions.SslProtocol, false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
_logger.Verbose("Client '{0}' accepted by TCP listener '{1}, {2}'.",
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace MQTTnet.Internal
|
||||
{
|
||||
public class BlockingQueue<TItem>
|
||||
{
|
||||
private readonly object _syncRoot = new object();
|
||||
private readonly LinkedList<TItem> _items = new LinkedList<TItem>();
|
||||
private readonly ManualResetEvent _gate = new ManualResetEvent(false);
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return _items.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Enqueue(TItem item)
|
||||
{
|
||||
if (item == null) throw new ArgumentNullException(nameof(item));
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_items.AddLast(item);
|
||||
_gate.Set();
|
||||
}
|
||||
}
|
||||
|
||||
public TItem Dequeue()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_items.Count > 0)
|
||||
{
|
||||
var item = _items.First.Value;
|
||||
_items.RemoveFirst();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
if (_items.Count == 0)
|
||||
{
|
||||
_gate.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
_gate.WaitOne();
|
||||
}
|
||||
}
|
||||
|
||||
public TItem RemoveFirst()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
var item = _items.First;
|
||||
_items.RemoveFirst();
|
||||
|
||||
return item.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_items.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='uap10.0'">
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.1.5" />
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.1.9" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net452'">
|
||||
|
||||
@@ -16,8 +16,14 @@ namespace MQTTnet.Server
|
||||
|
||||
IMqttServerOptions Options { get; }
|
||||
|
||||
[Obsolete("This method is no longer async. Use the not async method.")]
|
||||
Task<IList<IMqttClientSessionStatus>> GetClientSessionsStatusAsync();
|
||||
|
||||
IList<IMqttClientSessionStatus> GetClientSessionsStatus();
|
||||
|
||||
IList<MqttApplicationMessage> GetRetainedMessages();
|
||||
Task ClearRetainedMessagesAsync();
|
||||
|
||||
Task SubscribeAsync(string clientId, IList<TopicFilter> topicFilters);
|
||||
Task UnsubscribeAsync(string clientId, IList<string> topicFilters);
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace MQTTnet.Server
|
||||
{
|
||||
IMqttServer CreateMqttServer();
|
||||
|
||||
IMqttServer CreateMqttServer(IMqttNetLogger logger);
|
||||
|
||||
IMqttServer CreateMqttServer(IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger);
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace MQTTnet.Server
|
||||
Action<MqttConnectionValidatorContext> ConnectionValidator { get; }
|
||||
Action<MqttSubscriptionInterceptorContext> SubscriptionInterceptor { get; }
|
||||
Action<MqttApplicationMessageInterceptorContext> ApplicationMessageInterceptor { get; }
|
||||
Action<MqttClientMessageQueueInterceptorContext> ClientMessageQueueInterceptor { get; set; }
|
||||
Action<MqttClientMessageQueueInterceptorContext> ClientMessageQueueInterceptor { get; }
|
||||
|
||||
MqttServerTcpEndpointOptions DefaultEndpointOptions { get; }
|
||||
MqttServerTlsTcpEndpointOptions TlsEndpointOptions { get; }
|
||||
|
||||
@@ -137,7 +137,9 @@ namespace MQTTnet.Server
|
||||
|
||||
_cleanupHandle?.Dispose();
|
||||
_cleanupHandle = null;
|
||||
|
||||
|
||||
_adapter = null;
|
||||
_cancellationTokenSource?.Cancel(false);
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
}
|
||||
@@ -289,7 +291,9 @@ namespace MQTTnet.Server
|
||||
{
|
||||
_pendingPacketsQueue?.Dispose();
|
||||
|
||||
_cancellationTokenSource?.Cancel ();
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
}
|
||||
|
||||
private void ProcessReceivedPacket(IMqttChannelAdapter adapter, MqttBasePacket packet, CancellationToken cancellationToken)
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace MQTTnet.Server
|
||||
return Task.Run(() => RunSession(clientAdapter, _cancellationToken), _cancellationToken);
|
||||
}
|
||||
|
||||
public Task<IList<IMqttClientSessionStatus>> GetClientStatusAsync()
|
||||
public IList<IMqttClientSessionStatus> GetClientStatus()
|
||||
{
|
||||
var result = new List<IMqttClientSessionStatus>();
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace MQTTnet.Server
|
||||
result.Add(status);
|
||||
}
|
||||
|
||||
return Task.FromResult((IList<IMqttClientSessionStatus>)result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void EnqueueApplicationMessage(MqttClientSession senderClientSession, MqttPublishPacket publishPacket)
|
||||
|
||||
@@ -52,7 +52,51 @@ namespace MQTTnet.Server
|
||||
|
||||
try
|
||||
{
|
||||
await HandleMessageInternalAsync(clientId, applicationMessage).ConfigureAwait(false);
|
||||
List<MqttApplicationMessage> messagesForSave = null;
|
||||
lock (_messages)
|
||||
{
|
||||
var saveIsRequired = false;
|
||||
|
||||
if (applicationMessage.Payload?.Length == 0)
|
||||
{
|
||||
saveIsRequired = _messages.Remove(applicationMessage.Topic);
|
||||
_logger.Verbose("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_messages.TryGetValue(applicationMessage.Topic, out var existingMessage))
|
||||
{
|
||||
_messages[applicationMessage.Topic] = applicationMessage;
|
||||
saveIsRequired = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (existingMessage.QualityOfServiceLevel != applicationMessage.QualityOfServiceLevel || !existingMessage.Payload.SequenceEqual(applicationMessage.Payload ?? new byte[0]))
|
||||
{
|
||||
_messages[applicationMessage.Topic] = applicationMessage;
|
||||
saveIsRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Verbose("Client '{0}' set retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
}
|
||||
|
||||
if (saveIsRequired)
|
||||
{
|
||||
messagesForSave = new List<MqttApplicationMessage>(_messages.Values);
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesForSave == null)
|
||||
{
|
||||
_logger.Verbose("Skipped saving retained messages because no changes were detected.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_options.Storage != null)
|
||||
{
|
||||
await _options.Storage.SaveRetainedMessagesAsync(messagesForSave).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
@@ -84,52 +128,27 @@ namespace MQTTnet.Server
|
||||
return retainedMessages;
|
||||
}
|
||||
|
||||
private async Task HandleMessageInternalAsync(string clientId, MqttApplicationMessage applicationMessage)
|
||||
public IList<MqttApplicationMessage> GetMessages()
|
||||
{
|
||||
var saveIsRequired = false;
|
||||
|
||||
lock (_messages)
|
||||
{
|
||||
if (applicationMessage.Payload?.Length == 0)
|
||||
{
|
||||
saveIsRequired = _messages.Remove(applicationMessage.Topic);
|
||||
_logger.Info("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_messages.TryGetValue(applicationMessage.Topic, out var existingMessage))
|
||||
{
|
||||
_messages[applicationMessage.Topic] = applicationMessage;
|
||||
saveIsRequired = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (existingMessage.QualityOfServiceLevel != applicationMessage.QualityOfServiceLevel || !existingMessage.Payload.SequenceEqual(applicationMessage.Payload ?? new byte[0]))
|
||||
{
|
||||
_messages[applicationMessage.Topic] = applicationMessage;
|
||||
saveIsRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Info("Client '{0}' set retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||
}
|
||||
return _messages.Values.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
if (!saveIsRequired)
|
||||
public Task ClearMessagesAsync()
|
||||
{
|
||||
lock (_messages)
|
||||
{
|
||||
_logger.Verbose("Skipped saving retained messages because no changes were detected.");
|
||||
_messages.Clear();
|
||||
}
|
||||
|
||||
if (saveIsRequired && _options.Storage != null)
|
||||
if (_options.Storage != null)
|
||||
{
|
||||
List<MqttApplicationMessage> messages;
|
||||
lock (_messages)
|
||||
{
|
||||
messages = _messages.Values.ToList();
|
||||
}
|
||||
|
||||
await _options.Storage.SaveRetainedMessagesAsync(messages).ConfigureAwait(false);
|
||||
return _options.Storage.SaveRetainedMessagesAsync(new List<MqttApplicationMessage>());
|
||||
}
|
||||
|
||||
return Task.FromResult((object)null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,17 @@ namespace MQTTnet.Server
|
||||
|
||||
public Task<IList<IMqttClientSessionStatus>> GetClientSessionsStatusAsync()
|
||||
{
|
||||
return _clientSessionsManager.GetClientStatusAsync();
|
||||
return Task.FromResult(_clientSessionsManager.GetClientStatus());
|
||||
}
|
||||
|
||||
public IList<IMqttClientSessionStatus> GetClientSessionsStatus()
|
||||
{
|
||||
return _clientSessionsManager.GetClientStatus();
|
||||
}
|
||||
|
||||
public IList<MqttApplicationMessage> GetRetainedMessages()
|
||||
{
|
||||
return _retainedMessagesManager.GetMessages();
|
||||
}
|
||||
|
||||
public Task SubscribeAsync(string clientId, IList<TopicFilter> topicFilters)
|
||||
@@ -129,6 +139,11 @@ namespace MQTTnet.Server
|
||||
}
|
||||
}
|
||||
|
||||
public Task ClearRetainedMessagesAsync()
|
||||
{
|
||||
return _retainedMessagesManager?.ClearMessagesAsync();
|
||||
}
|
||||
|
||||
internal void OnClientConnected(string clientId)
|
||||
{
|
||||
_logger.Info("Client '{0}': Connected.", clientId);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Security.Authentication;
|
||||
|
||||
namespace MQTTnet.Server
|
||||
{
|
||||
@@ -80,6 +81,12 @@ namespace MQTTnet.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttServerOptionsBuilder WithEncryptionSslProtocol(SslProtocols value)
|
||||
{
|
||||
_options.TlsEndpointOptions.SslProtocol = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttServerOptionsBuilder WithoutEncryptedEndpoint()
|
||||
{
|
||||
_options.TlsEndpointOptions.IsEnabled = false;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace MQTTnet.Server
|
||||
using System.Security.Authentication;
|
||||
|
||||
namespace MQTTnet.Server
|
||||
{
|
||||
public class MqttServerTlsTcpEndpointOptions : MqttServerTcpEndpointBaseOptions
|
||||
{
|
||||
@@ -8,5 +10,8 @@
|
||||
}
|
||||
|
||||
public byte[] Certificate { get; set; }
|
||||
|
||||
|
||||
public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user