diff --git a/Frameworks/MQTTnet.NetCoreApp/MqttClientFactory.cs b/Frameworks/MQTTnet.NetCoreApp/MqttClientFactory.cs
index 4da24a1..62b6569 100644
--- a/Frameworks/MQTTnet.NetCoreApp/MqttClientFactory.cs
+++ b/Frameworks/MQTTnet.NetCoreApp/MqttClientFactory.cs
@@ -1,5 +1,6 @@
using System;
using MQTTnet.Core.Adapter;
+using MQTTnet.Core.Channel;
using MQTTnet.Core.Client;
using MQTTnet.Core.Serializer;
@@ -11,7 +12,11 @@ namespace MQTTnet
{
if (options == null) throw new ArgumentNullException(nameof(options));
- return new MqttClient(options, new MqttChannelCommunicationAdapter(new MqttTcpChannel(), new DefaultMqttV311PacketSerializer()));
+ return new MqttClient(options,
+ // The cast to IMqttCommunicationChannel is required... Roslyn is too stupid to
+ // figure out how to cast back to the base type
+ new MqttChannelCommunicationAdapter(options.UseSSL ? new MqttClientSslChannel() : (IMqttCommunicationChannel) new MqttTcpChannel(),
+ new DefaultMqttV311PacketSerializer()));
}
}
}
diff --git a/Frameworks/MQTTnet.NetCoreApp/MqttClientSslChannel.cs b/Frameworks/MQTTnet.NetCoreApp/MqttClientSslChannel.cs
new file mode 100644
index 0000000..26b12fb
--- /dev/null
+++ b/Frameworks/MQTTnet.NetCoreApp/MqttClientSslChannel.cs
@@ -0,0 +1,122 @@
+using System;
+using System.IO;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Threading.Tasks;
+using MQTTnet.Core.Channel;
+using MQTTnet.Core.Client;
+using MQTTnet.Core.Exceptions;
+
+namespace MQTTnet
+{
+ ///
+ /// Describes an SSL channel to an MQTT server.
+ ///
+ public class MqttClientSslChannel : IMqttCommunicationChannel, IDisposable
+ {
+ private readonly Socket _socket;
+ private SslStream _sslStream;
+
+ ///
+ /// Creates a new .
+ ///
+ public MqttClientSslChannel()
+ {
+ _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ }
+
+ ///
+ /// Creates a new with a predefined .
+ ///
+ ///
+ public MqttClientSslChannel(Socket socket)
+ {
+ _socket = socket ?? throw new ArgumentNullException(nameof(socket));
+ }
+
+ ///
+ /// Asynchronously connects to the host described in the .
+ ///
+ /// The describing the connection.
+ public async Task ConnectAsync(MqttClientOptions options)
+ {
+ try
+ {
+ await _socket.ConnectAsync(options.Server, options.Port);
+
+ NetworkStream ns = new NetworkStream(_socket, true);
+ _sslStream = new SslStream(ns);
+
+ await _sslStream.AuthenticateAsClientAsync(options.Server, null, SslProtocols.Tls12, false);
+
+ }
+ catch (SocketException exception)
+ {
+ throw new MqttCommunicationException(exception);
+ }
+ }
+
+ ///
+ /// Asynchronously disconnects the client from the server.
+ ///
+ public Task DisconnectAsync()
+ {
+ try
+ {
+ _socket.Dispose();
+ return Task.FromResult(0);
+ }
+ catch (SocketException exception)
+ {
+ throw new MqttCommunicationException(exception);
+ }
+ }
+
+ ///
+ /// Asynchronously writes a sequence of bytes to the socket.
+ ///
+ /// The buffer to write data from.
+ public async Task WriteAsync(byte[] buffer)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer));
+
+ try
+ {
+ await _sslStream.WriteAsync(buffer, 0, buffer.Length);
+ }
+ catch (Exception ex)
+ when (ex is SocketException || ex is IOException)
+ {
+ throw new MqttCommunicationException(ex);
+ }
+ }
+
+ ///
+ /// Asynchronously reads a sequence of bytes from the socket.
+ ///
+ /// The buffer to write the data into.
+ public async Task ReadAsync(byte[] buffer)
+ {
+ try
+ {
+ await _sslStream.ReadAsync(buffer, 0, buffer.Length);
+ }
+ catch (Exception ex)
+ when (ex is SocketException || ex is IOException)
+ {
+ throw new MqttCommunicationException(ex);
+ }
+ }
+
+ ///
+ /// Releases all resources used by the .
+ ///
+ public void Dispose()
+ {
+ _sslStream?.Dispose();
+ _socket?.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Frameworks/MQTTnet.NetCoreApp/MqttServerFactory.cs b/Frameworks/MQTTnet.NetCoreApp/MqttServerFactory.cs
index a725426..5098ea2 100644
--- a/Frameworks/MQTTnet.NetCoreApp/MqttServerFactory.cs
+++ b/Frameworks/MQTTnet.NetCoreApp/MqttServerFactory.cs
@@ -1,4 +1,5 @@
using System;
+using MQTTnet.Core.Adapter;
using MQTTnet.Core.Server;
namespace MQTTnet
@@ -9,7 +10,8 @@ namespace MQTTnet
{
if (options == null) throw new ArgumentNullException(nameof(options));
- return new MqttServer(options, new MqttServerAdapter());
+ // The cast to IMqttServerAdapter is required... stupidly...
+ return new MqttServer(options, options.UseSSL ? (IMqttServerAdapter)new MqttSslServerAdapter() : new MqttServerAdapter());
}
}
}
diff --git a/Frameworks/MQTTnet.NetCoreApp/MqttServerSslChannel.cs b/Frameworks/MQTTnet.NetCoreApp/MqttServerSslChannel.cs
new file mode 100644
index 0000000..c4c5713
--- /dev/null
+++ b/Frameworks/MQTTnet.NetCoreApp/MqttServerSslChannel.cs
@@ -0,0 +1,123 @@
+using System;
+using System.IO;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading.Tasks;
+using MQTTnet.Core.Channel;
+using MQTTnet.Core.Client;
+using MQTTnet.Core.Exceptions;
+
+namespace MQTTnet
+{
+ ///
+ /// Describes an SSL channel to a client.
+ ///
+ public class MqttServerSslChannel : IMqttCommunicationChannel, IDisposable
+ {
+ private readonly Socket _socket;
+ private readonly SslStream _sslStream;
+ private readonly X509Certificate2 _cert;
+
+ ///
+ /// Creates a new with a predefined .
+ ///
+ /// The client socket.
+ /// The X509 certificate used to authenticate as a server.
+ public MqttServerSslChannel(Socket socket, X509Certificate2 cert)
+ {
+ _socket = socket ?? throw new ArgumentNullException(nameof(socket));
+ _cert = cert ?? throw new ArgumentNullException(nameof(cert));
+
+ if (_socket.Connected)
+ {
+ NetworkStream ns = new NetworkStream(_socket, true);
+ _sslStream = new SslStream(ns);
+ }
+ }
+
+ public async Task Authenticate()
+ {
+ await _sslStream.AuthenticateAsServerAsync(_cert, false, SslProtocols.Tls12, false);
+ }
+
+ ///
+ /// Asynchronously connects to the client described in the .
+ ///
+ /// The describing the connection.
+ public async Task ConnectAsync(MqttClientOptions options)
+ {
+ try
+ {
+ await _socket.ConnectAsync(options.Server, options.Port);
+ }
+ catch (SocketException exception)
+ {
+ throw new MqttCommunicationException(exception);
+ }
+ }
+
+ ///
+ /// Asynchronously disconnects the client from the server.
+ ///
+ public Task DisconnectAsync()
+ {
+ try
+ {
+ _socket.Dispose();
+ return Task.FromResult(0);
+ }
+ catch (SocketException exception)
+ {
+ throw new MqttCommunicationException(exception);
+ }
+ }
+
+ ///
+ /// Asynchronously writes a sequence of bytes to the socket.
+ ///
+ /// The buffer to write data from.
+ public async Task WriteAsync(byte[] buffer)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer));
+
+ try
+ {
+ await _sslStream.WriteAsync(buffer, 0, buffer.Length);
+ }
+ catch (Exception ex)
+ when (ex is SocketException || ex is IOException)
+ {
+ throw new MqttCommunicationException(ex);
+ }
+ }
+
+ ///
+ /// Asynchronously reads a sequence of bytes from the socket.
+ ///
+ /// The buffer to write the data into.
+ public async Task ReadAsync(byte[] buffer)
+ {
+ try
+ {
+ await _sslStream.ReadAsync(buffer, 0, buffer.Length);
+ }
+ catch (Exception ex)
+ when (ex is SocketException || ex is IOException)
+ {
+ throw new MqttCommunicationException(ex);
+ }
+ }
+
+ ///
+ /// Releases all resources used by the .
+ ///
+ public void Dispose()
+ {
+ _sslStream?.Dispose();
+ _socket?.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Frameworks/MQTTnet.NetCoreApp/MqttSslServerAdapter.cs b/Frameworks/MQTTnet.NetCoreApp/MqttSslServerAdapter.cs
new file mode 100644
index 0000000..58b0a3b
--- /dev/null
+++ b/Frameworks/MQTTnet.NetCoreApp/MqttSslServerAdapter.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using MQTTnet.Core.Adapter;
+using MQTTnet.Core.Serializer;
+using MQTTnet.Core.Server;
+
+namespace MQTTnet
+{
+ public class MqttSslServerAdapter : IMqttServerAdapter, IDisposable
+ {
+ private CancellationTokenSource _cancellationTokenSource;
+ private Socket _socket;
+ private X509Certificate2 _x590Certificate2;
+
+ public event EventHandler ClientConnected;
+
+ public void Start(MqttServerOptions options)
+ {
+ if (_socket != null) throw new InvalidOperationException("Server is already started.");
+
+ _cancellationTokenSource = new CancellationTokenSource();
+
+ _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ _socket.Bind(new IPEndPoint(IPAddress.Any, options.Port));
+ _socket.Listen(options.ConnectionBacklog);
+
+ Task.Run(async () => await AcceptConnectionsAsync(_cancellationTokenSource.Token), _cancellationTokenSource.Token);
+
+ _x590Certificate2 = new X509Certificate2(options.CertificatePath);
+ }
+
+ public void Stop()
+ {
+ _cancellationTokenSource?.Dispose();
+ _cancellationTokenSource = null;
+
+ _socket?.Dispose();
+ _socket = null;
+ }
+
+ public void Dispose()
+ {
+ Stop();
+ }
+
+ private async Task AcceptConnectionsAsync(CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ var clientSocket = await _socket.AcceptAsync();
+
+ MqttServerSslChannel mssc = new MqttServerSslChannel(clientSocket, _x590Certificate2);
+ await mssc.Authenticate();
+
+ var clientAdapter = new MqttChannelCommunicationAdapter(mssc, new DefaultMqttV311PacketSerializer());
+ ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Frameworks/MQTTnet.NetFramework/MQTTnet.NetFramework.csproj b/Frameworks/MQTTnet.NetFramework/MQTTnet.NetFramework.csproj
index 0c63762..314c158 100644
--- a/Frameworks/MQTTnet.NetFramework/MQTTnet.NetFramework.csproj
+++ b/Frameworks/MQTTnet.NetFramework/MQTTnet.NetFramework.csproj
@@ -103,6 +103,9 @@
+
+
+
diff --git a/Frameworks/MQTTnet.NetFramework/MqttClientFactory.cs b/Frameworks/MQTTnet.NetFramework/MqttClientFactory.cs
index 4da24a1..048112f 100644
--- a/Frameworks/MQTTnet.NetFramework/MqttClientFactory.cs
+++ b/Frameworks/MQTTnet.NetFramework/MqttClientFactory.cs
@@ -1,5 +1,6 @@
using System;
using MQTTnet.Core.Adapter;
+using MQTTnet.Core.Channel;
using MQTTnet.Core.Client;
using MQTTnet.Core.Serializer;
@@ -10,8 +11,12 @@ namespace MQTTnet
public MqttClient CreateMqttClient(MqttClientOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));
-
- return new MqttClient(options, new MqttChannelCommunicationAdapter(new MqttTcpChannel(), new DefaultMqttV311PacketSerializer()));
+
+ return new MqttClient(options,
+ // The cast to IMqttCommunicationChannel is required... Roslyn is too stupid to
+ // figure out how to cast back to the base type
+ new MqttChannelCommunicationAdapter(options.UseSSL ? new MqttClientSslChannel() : (IMqttCommunicationChannel)new MqttTcpChannel(),
+ new DefaultMqttV311PacketSerializer()));
}
}
}
diff --git a/Frameworks/MQTTnet.NetFramework/MqttClientSslChannel.cs b/Frameworks/MQTTnet.NetFramework/MqttClientSslChannel.cs
new file mode 100644
index 0000000..8adf14b
--- /dev/null
+++ b/Frameworks/MQTTnet.NetFramework/MqttClientSslChannel.cs
@@ -0,0 +1,122 @@
+using System;
+using System.IO;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Threading.Tasks;
+using MQTTnet.Core.Channel;
+using MQTTnet.Core.Client;
+using MQTTnet.Core.Exceptions;
+
+namespace MQTTnet
+{
+ ///
+ /// Describes an SSL channel to an MQTT server.
+ ///
+ public class MqttClientSslChannel : IMqttCommunicationChannel, IDisposable
+ {
+ private readonly Socket _socket;
+ private SslStream _sslStream;
+
+ ///
+ /// Creates a new .
+ ///
+ public MqttClientSslChannel()
+ {
+ _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ }
+
+ ///
+ /// Creates a new with a predefined .
+ ///
+ ///
+ public MqttClientSslChannel(Socket socket)
+ {
+ _socket = socket ?? throw new ArgumentNullException(nameof(socket));
+ }
+
+ ///
+ /// Asynchronously connects to the host described in the .
+ ///
+ /// The describing the connection.
+ public async Task ConnectAsync(MqttClientOptions options)
+ {
+ try
+ {
+ await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, options.Server, options.Port,
+ null);
+
+ NetworkStream ns = new NetworkStream(_socket, true);
+ _sslStream = new SslStream(ns);
+
+ await _sslStream.AuthenticateAsClientAsync(options.Server, null, SslProtocols.Tls12, false);
+
+ }
+ catch (SocketException exception)
+ {
+ throw new MqttCommunicationException(exception);
+ }
+ }
+
+ ///
+ /// Asynchronously disconnects the client from the server.
+ ///
+ public async Task DisconnectAsync()
+ {
+ try
+ {
+ await Task.Factory.FromAsync(_socket.BeginDisconnect, _socket.EndDisconnect, true, null);
+ }
+ catch (SocketException exception)
+ {
+ throw new MqttCommunicationException(exception);
+ }
+ }
+
+ ///
+ /// Asynchronously writes a sequence of bytes to the socket.
+ ///
+ /// The buffer to write data from.
+ public async Task WriteAsync(byte[] buffer)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer));
+
+ try
+ {
+ await _sslStream.WriteAsync(buffer, 0, buffer.Length);
+ }
+ catch (Exception ex)
+ when (ex is SocketException || ex is IOException)
+ {
+ throw new MqttCommunicationException(ex);
+ }
+ }
+
+ ///
+ /// Asynchronously reads a sequence of bytes from the socket.
+ ///
+ /// The buffer to write the data into.
+ public async Task ReadAsync(byte[] buffer)
+ {
+ try
+ {
+ await _sslStream.ReadAsync(buffer, 0, buffer.Length);
+ }
+ catch (Exception ex)
+ when (ex is SocketException || ex is IOException)
+ {
+ throw new MqttCommunicationException(ex);
+ }
+ }
+
+ ///
+ /// Releases all resources used by the .
+ ///
+ public void Dispose()
+ {
+ _sslStream?.Dispose();
+ _socket?.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Frameworks/MQTTnet.NetFramework/MqttServerFactory.cs b/Frameworks/MQTTnet.NetFramework/MqttServerFactory.cs
index a725426..a26fbdb 100644
--- a/Frameworks/MQTTnet.NetFramework/MqttServerFactory.cs
+++ b/Frameworks/MQTTnet.NetFramework/MqttServerFactory.cs
@@ -1,4 +1,5 @@
using System;
+using MQTTnet.Core.Adapter;
using MQTTnet.Core.Server;
namespace MQTTnet
@@ -8,8 +9,9 @@ namespace MQTTnet
public MqttServer CreateMqttServer(MqttServerOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));
-
- return new MqttServer(options, new MqttServerAdapter());
+
+ // The cast to IMqttServerAdapter is required... stupidly...
+ return new MqttServer(options, options.UseSSL ? (IMqttServerAdapter) new MqttSslServerAdapter() : new MqttServerAdapter());
}
}
}
diff --git a/Frameworks/MQTTnet.NetFramework/MqttServerSslChannel.cs b/Frameworks/MQTTnet.NetFramework/MqttServerSslChannel.cs
new file mode 100644
index 0000000..2f01462
--- /dev/null
+++ b/Frameworks/MQTTnet.NetFramework/MqttServerSslChannel.cs
@@ -0,0 +1,123 @@
+using System;
+using System.IO;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading.Tasks;
+using MQTTnet.Core.Channel;
+using MQTTnet.Core.Client;
+using MQTTnet.Core.Exceptions;
+
+namespace MQTTnet
+{
+ ///
+ /// Describes an SSL channel to a client.
+ ///
+ public class MqttServerSslChannel : IMqttCommunicationChannel, IDisposable
+ {
+ private readonly Socket _socket;
+ private SslStream _sslStream;
+ private X509Certificate2 _cert;
+
+ ///
+ /// Creates a new with a predefined .
+ ///
+ /// The client socket.
+ /// The X509 certificate used to authenticate as a server.
+ public MqttServerSslChannel(Socket socket, X509Certificate2 cert)
+ {
+ _socket = socket ?? throw new ArgumentNullException(nameof(socket));
+ _cert = cert ?? throw new ArgumentNullException(nameof(cert));
+
+ if (_socket.Connected)
+ {
+ NetworkStream ns = new NetworkStream(_socket, true);
+ _sslStream = new SslStream(ns);
+ }
+ }
+
+ public async Task Authenticate()
+ {
+ await _sslStream.AuthenticateAsServerAsync(_cert, false, SslProtocols.Tls12, false);
+ }
+
+ ///
+ /// Asynchronously connects to the client described in the .
+ ///
+ /// The describing the connection.
+ public async Task ConnectAsync(MqttClientOptions options)
+ {
+ try
+ {
+ await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, options.Server, options.Port,
+ null);
+ }
+ catch (SocketException exception)
+ {
+ throw new MqttCommunicationException(exception);
+ }
+ }
+
+ ///
+ /// Asynchronously disconnects the client from the server.
+ ///
+ public async Task DisconnectAsync()
+ {
+ try
+ {
+ await Task.Factory.FromAsync(_socket.BeginDisconnect, _socket.EndDisconnect, true, null);
+ }
+ catch (SocketException exception)
+ {
+ throw new MqttCommunicationException(exception);
+ }
+ }
+
+ ///
+ /// Asynchronously writes a sequence of bytes to the socket.
+ ///
+ /// The buffer to write data from.
+ public async Task WriteAsync(byte[] buffer)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer));
+
+ try
+ {
+ await _sslStream.WriteAsync(buffer, 0, buffer.Length);
+ }
+ catch (Exception ex)
+ when (ex is SocketException || ex is IOException)
+ {
+ throw new MqttCommunicationException(ex);
+ }
+ }
+
+ ///
+ /// Asynchronously reads a sequence of bytes from the socket.
+ ///
+ /// The buffer to write the data into.
+ public async Task ReadAsync(byte[] buffer)
+ {
+ try
+ {
+ await _sslStream.ReadAsync(buffer, 0, buffer.Length);
+ }
+ catch (Exception ex)
+ when (ex is SocketException || ex is IOException)
+ {
+ throw new MqttCommunicationException(ex);
+ }
+ }
+
+ ///
+ /// Releases all resources used by the .
+ ///
+ public void Dispose()
+ {
+ _sslStream?.Dispose();
+ _socket?.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Frameworks/MQTTnet.NetFramework/MqttSslServerAdapter.cs b/Frameworks/MQTTnet.NetFramework/MqttSslServerAdapter.cs
new file mode 100644
index 0000000..f02c74b
--- /dev/null
+++ b/Frameworks/MQTTnet.NetFramework/MqttSslServerAdapter.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using MQTTnet.Core.Adapter;
+using MQTTnet.Core.Serializer;
+using MQTTnet.Core.Server;
+
+namespace MQTTnet
+{
+ public class MqttSslServerAdapter : IMqttServerAdapter, IDisposable
+ {
+ private CancellationTokenSource _cancellationTokenSource;
+ private Socket _socket;
+ private X509Certificate2 _x590Certificate2;
+
+ public event EventHandler ClientConnected;
+
+ public void Start(MqttServerOptions options)
+ {
+ if (_socket != null) throw new InvalidOperationException("Server is already started.");
+
+ _cancellationTokenSource = new CancellationTokenSource();
+
+ _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ _socket.Bind(new IPEndPoint(IPAddress.Any, options.Port));
+ _socket.Listen(options.ConnectionBacklog);
+
+ Task.Run(async () => await AcceptConnectionsAsync(_cancellationTokenSource.Token), _cancellationTokenSource.Token);
+
+ _x590Certificate2 = new X509Certificate2(options.CertificatePath);
+ }
+
+ public void Stop()
+ {
+ _cancellationTokenSource?.Dispose();
+ _cancellationTokenSource = null;
+
+ _socket?.Dispose();
+ _socket = null;
+ }
+
+ public void Dispose()
+ {
+ Stop();
+ }
+
+ private async Task AcceptConnectionsAsync(CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ var clientSocket = await Task.Factory.FromAsync(_socket.BeginAccept, _socket.EndAccept, null);
+
+ MqttServerSslChannel mssc = new MqttServerSslChannel(clientSocket, _x590Certificate2);
+ await mssc.Authenticate();
+
+ var clientAdapter = new MqttChannelCommunicationAdapter(mssc, new DefaultMqttV311PacketSerializer());
+ ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/MQTTnet.Core/Client/MqttClientOptions.cs b/MQTTnet.Core/Client/MqttClientOptions.cs
index 830fef5..d306bfe 100644
--- a/MQTTnet.Core/Client/MqttClientOptions.cs
+++ b/MQTTnet.Core/Client/MqttClientOptions.cs
@@ -19,5 +19,24 @@ namespace MQTTnet.Core.Client
public TimeSpan KeepAlivePeriod { get; set; } = TimeSpan.FromSeconds(5);
public TimeSpan DefaultCommunicationTimeout { get; set; } = TimeSpan.FromSeconds(10);
+
+ ///
+ /// Use SSL to communicate with the MQTT server.
+ ///
+ /// Setting this value to true will also set to 8883 if its value was 1883 (not set).
+ public bool UseSSL
+ {
+ get => _useSSL;
+ set
+ {
+ // Automatically set the port to the MQTT SSL port (8883) if it wasn't set already
+ if (value && Port == 1883)
+ Port = 8883;
+
+ _useSSL = value;
+ }
+ }
+
+ private bool _useSSL;
}
}
diff --git a/MQTTnet.Core/Server/MqttServerOptions.cs b/MQTTnet.Core/Server/MqttServerOptions.cs
index 0ce2309..0638700 100644
--- a/MQTTnet.Core/Server/MqttServerOptions.cs
+++ b/MQTTnet.Core/Server/MqttServerOptions.cs
@@ -13,5 +13,12 @@ namespace MQTTnet.Core.Server
public TimeSpan DefaultCommunicationTimeout { get; set; } = TimeSpan.FromSeconds(10);
public Func ConnectionValidator { get; set; }
+
+ public bool UseSSL = false;
+
+ ///
+ /// The path to the X509 SSL certificate.
+ ///
+ public string CertificatePath = string.Empty;
}
}