Files
MQTTnet/Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpServerAdapter.cs
T

119 lines
3.8 KiB
C#

#if NET452 || NET461 || NETSTANDARD1_3 || NETSTANDARD2_0
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Server;
namespace MQTTnet.Implementations
{
public class MqttTcpServerAdapter : IMqttServerAdapter
{
private readonly List<MqttTcpServerListener> _listeners = new List<MqttTcpServerListener>();
private readonly IMqttNetChildLogger _logger;
private CancellationTokenSource _cancellationTokenSource;
public MqttTcpServerAdapter(IMqttNetChildLogger logger)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger.CreateChildLogger(nameof(MqttTcpServerAdapter));
}
public event EventHandler<MqttServerAdapterClientAcceptedEventArgs> ClientAccepted;
public Task StartAsync(IMqttServerOptions options)
{
if (_cancellationTokenSource != null) throw new InvalidOperationException("Server is already started.");
_cancellationTokenSource = new CancellationTokenSource();
if (options.DefaultEndpointOptions.IsEnabled)
{
RegisterListeners(options.DefaultEndpointOptions);
}
if (options.TlsEndpointOptions.IsEnabled)
{
if (options.TlsEndpointOptions.Certificate == null)
{
throw new ArgumentException("TLS certificate is not set.");
}
var tlsCertificate = new X509Certificate2(options.TlsEndpointOptions.Certificate);
if (!tlsCertificate.HasPrivateKey)
{
throw new InvalidOperationException("The certificate for TLS encryption must contain the private key.");
}
RegisterListeners(options.TlsEndpointOptions);
}
return Task.FromResult(0);
}
public Task StopAsync()
{
Dispose();
return Task.FromResult(0);
}
public void Dispose()
{
_cancellationTokenSource?.Cancel(false);
_cancellationTokenSource?.Dispose();
_cancellationTokenSource = null;
foreach (var listener in _listeners)
{
listener.Dispose();
}
_listeners.Clear();
}
private void RegisterListeners(MqttServerTcpEndpointBaseOptions options)
{
var tlsOptions = options as MqttServerTlsTcpEndpointOptions;
X509Certificate2 tlsCertificate = null;
if (tlsOptions != null)
{
tlsCertificate = new X509Certificate2(tlsOptions.Certificate);
}
var listenerV4 = new MqttTcpServerListener(
AddressFamily.InterNetwork,
options,
tlsCertificate,
_cancellationTokenSource.Token,
_logger);
listenerV4.ClientAccepted += OnClientAccepted;
listenerV4.Start();
_listeners.Add(listenerV4);
var listenerV6 = new MqttTcpServerListener(
AddressFamily.InterNetworkV6,
options,
tlsCertificate,
_cancellationTokenSource.Token,
_logger);
listenerV6.ClientAccepted += OnClientAccepted;
listenerV6.Start();
_listeners.Add(listenerV6);
}
private void OnClientAccepted(object sender, MqttServerAdapterClientAcceptedEventArgs e)
{
ClientAccepted?.Invoke(this, e);
}
}
}
#endif