Merge branch 'develop' into client-cancel-task

This commit is contained in:
Christian
2018-09-28 22:49:00 +02:00
committed by GitHub
31 changed files with 557 additions and 154 deletions
@@ -7,5 +7,9 @@ namespace MQTTnet.Client
IMqttClient CreateMqttClient();
IMqttClient CreateMqttClient(IMqttNetLogger logger);
IMqttClient CreateMqttClient(IMqttClientAdapterFactory adapterFactory);
IMqttClient CreateMqttClient(IMqttNetLogger logger, IMqttClientAdapterFactory adapterFactory);
}
}
+21 -7
View File
@@ -25,10 +25,11 @@ namespace MQTTnet.Client
private IMqttClientOptions _options;
private CancellationTokenSource _cancellationTokenSource;
private Task _packetReceiverTask;
private Task _keepAliveMessageSenderTask;
internal Task _packetReceiverTask;
internal Task _keepAliveMessageSenderTask;
private IMqttChannelAdapter _adapter;
private bool _cleanDisconnectInitiated;
private TaskCompletionSource<bool> _disconnectReason;
public MqttClient(IMqttClientAdapterFactory channelFactory, IMqttNetLogger logger)
{
@@ -54,6 +55,7 @@ namespace MQTTnet.Client
try
{
_cancellationTokenSource = new CancellationTokenSource();
_disconnectReason = new TaskCompletionSource<bool>();
_options = options;
_packetIdentifierProvider.Reset();
_packetDispatcher.Reset();
@@ -85,8 +87,10 @@ namespace MQTTnet.Client
catch (Exception exception)
{
_logger.Error(exception, "Error while connecting with server.");
await DisconnectInternalAsync(null, exception).ConfigureAwait(false);
if (_disconnectReason.TrySetException(exception))
{
await DisconnectInternalAsync(null, exception).ConfigureAwait(false);
}
throw;
}
}
@@ -104,7 +108,10 @@ namespace MQTTnet.Client
}
finally
{
await DisconnectInternalAsync(null, null).ConfigureAwait(false);
if (_disconnectReason.TrySetCanceled())
{
await DisconnectInternalAsync(null, null).ConfigureAwait(false);
}
}
}
@@ -351,7 +358,10 @@ namespace MQTTnet.Client
_logger.Error(exception, "Unhandled exception while sending/receiving keep alive packets.");
}
await DisconnectInternalAsync(_keepAliveMessageSenderTask, exception).ConfigureAwait(false);
if (_disconnectReason.TrySetException(exception))
{
await DisconnectInternalAsync(_keepAliveMessageSenderTask, exception).ConfigureAwait(false);
}
}
finally
{
@@ -395,7 +405,11 @@ namespace MQTTnet.Client
}
_packetDispatcher.Dispatch(exception);
await DisconnectInternalAsync(_packetReceiverTask, exception).ConfigureAwait(false);
if (_disconnectReason.TrySetException(exception))
{
await DisconnectInternalAsync(_packetReceiverTask, exception).ConfigureAwait(false);
}
}
finally
{
@@ -7,10 +7,11 @@ namespace MQTTnet.Client
public class MqttClientOptionsBuilder
{
private readonly MqttClientOptions _options = new MqttClientOptions();
private MqttClientTcpOptions _tcpOptions;
private MqttClientWebSocketOptions _webSocketOptions;
private MqttClientTlsOptions _tlsOptions;
private MqttClientOptionsBuilderTlsParameters _tlsParameters;
private MqttClientWebSocketProxyOptions _proxyOptions;
public MqttClientOptionsBuilder WithProtocolVersion(MqttProtocolVersion value)
{
@@ -76,6 +77,21 @@ namespace MQTTnet.Client
return this;
}
public MqttClientOptionsBuilder WithProxy(string address, string username = null, string password = null, string domain = null, bool bypassOnLocal = false, string[] bypassList = null)
{
_proxyOptions = new MqttClientWebSocketProxyOptions
{
Address = address,
Username = username,
Password = password,
Domain = domain,
BypassOnLocal = bypassOnLocal,
BypassList = bypassList
};
return this;
}
public MqttClientOptionsBuilder WithWebSocketServer(string uri)
{
_webSocketOptions = new MqttClientWebSocketOptions
@@ -86,13 +102,25 @@ namespace MQTTnet.Client
return this;
}
public MqttClientOptionsBuilder WithTls(MqttClientOptionsBuilderTlsParameters parameters)
{
_tlsParameters = parameters ?? throw new ArgumentNullException(nameof(parameters));
return this;
}
public MqttClientOptionsBuilder WithTls()
{
return WithTls(new MqttClientOptionsBuilderTlsParameters { UseTls = true });
}
[Obsolete("Use method _WithTls_ which accepts the _MqttClientOptionsBuilderTlsParameters_.")]
public MqttClientOptionsBuilder WithTls(
bool allowUntrustedCertificates = false,
bool ignoreCertificateChainErrors = false,
bool ignoreCertificateRevocationErrors = false,
params byte[][] certificates)
{
_tlsOptions = new MqttClientTlsOptions
_tlsParameters = new MqttClientOptionsBuilderTlsParameters
{
UseTls = true,
AllowUntrustedCertificates = allowUntrustedCertificates,
@@ -104,33 +132,47 @@ namespace MQTTnet.Client
return this;
}
public MqttClientOptionsBuilder WithTls()
{
_tlsOptions = new MqttClientTlsOptions
{
UseTls = true
};
return this;
}
public IMqttClientOptions Build()
{
if (_tlsOptions != null)
if (_tcpOptions == null && _webSocketOptions == null)
{
if (_tcpOptions == null && _webSocketOptions == null)
throw new InvalidOperationException("A channel must be set.");
}
if (_tlsParameters != null)
{
if (_tlsParameters?.UseTls == true)
{
throw new InvalidOperationException("A channel (TCP or WebSocket) must be set if TLS is configured.");
var tlsOptions = new MqttClientTlsOptions
{
UseTls = true,
SslProtocol = _tlsParameters.SslProtocol,
AllowUntrustedCertificates = _tlsParameters.AllowUntrustedCertificates,
Certificates = _tlsParameters.Certificates?.Select(c => c.ToArray()).ToList(),
CertificateValidationCallback = _tlsParameters.CertificateValidationCallback,
IgnoreCertificateChainErrors = _tlsParameters.IgnoreCertificateChainErrors,
IgnoreCertificateRevocationErrors = _tlsParameters.IgnoreCertificateRevocationErrors
};
if (_tcpOptions != null)
{
_tcpOptions.TlsOptions = tlsOptions;
}
else if (_webSocketOptions != null)
{
_webSocketOptions.TlsOptions = tlsOptions;
}
}
}
if (_proxyOptions != null)
{
if (_webSocketOptions == null)
{
throw new InvalidOperationException("Proxies are only supported for WebSocket connections.");
}
if (_tcpOptions != null)
{
_tcpOptions.TlsOptions = _tlsOptions;
}
else if (_webSocketOptions != null)
{
_webSocketOptions.TlsOptions = _tlsOptions;
}
_webSocketOptions.ProxyOptions = _proxyOptions;
}
_options.ChannelOptions = (IMqttClientChannelOptions)_tcpOptions ?? _webSocketOptions;
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
namespace MQTTnet.Client
{
public class MqttClientOptionsBuilderTlsParameters
{
public bool UseTls { get; set; }
public Func<X509Certificate, X509Chain, SslPolicyErrors, IMqttClientOptions, bool> CertificateValidationCallback
{
get;
set;
}
public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12;
public IEnumerable<IEnumerable<byte>> Certificates { get; set; }
public bool AllowUntrustedCertificates { get; set; }
public bool IgnoreCertificateChainErrors { get; set; }
public bool IgnoreCertificateRevocationErrors { get; set; }
}
}
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Authentication;
namespace MQTTnet.Client
{
@@ -17,6 +18,8 @@ namespace MQTTnet.Client
public List<byte[]> Certificates { get; set; }
public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12;
public Func<X509Certificate, X509Chain, SslPolicyErrors, IMqttClientOptions, bool> CertificateValidationCallback { get; set; }
}
}
@@ -13,6 +13,8 @@ namespace MQTTnet.Client
public CookieContainer CookieContainer { get; set; }
public MqttClientWebSocketProxyOptions ProxyOptions { get; set; }
public MqttClientTlsOptions TlsOptions { get; set; } = new MqttClientTlsOptions();
public override string ToString()
@@ -0,0 +1,17 @@
namespace MQTTnet.Client
{
public class MqttClientWebSocketProxyOptions
{
public string Address { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Domain { get; set; }
public bool BypassOnLocal { get; set; }
public string[] BypassList { get; set; }
}
}