using System; using System.Threading.Tasks; using MQTTnet.Core.Adapter; using MQTTnet.Core.Server; using Windows.Networking.Sockets; using Microsoft.Extensions.Logging; namespace MQTTnet.Implementations { public class MqttServerAdapter : IMqttServerAdapter, IDisposable { private readonly ILogger _logger; private readonly IMqttCommunicationAdapterFactory _mqttCommunicationAdapterFactory; private StreamSocketListener _defaultEndpointSocket; public MqttServerAdapter(ILogger logger, IMqttCommunicationAdapterFactory mqttCommunicationAdapterFactory) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _mqttCommunicationAdapterFactory = mqttCommunicationAdapterFactory ?? throw new ArgumentNullException(nameof(mqttCommunicationAdapterFactory)); } public event EventHandler ClientAccepted; public async Task StartAsync(MqttServerOptions options) { if (options == null) throw new ArgumentNullException(nameof(options)); if (_defaultEndpointSocket != null) throw new InvalidOperationException("Server is already started."); if (options.DefaultEndpointOptions.IsEnabled) { _defaultEndpointSocket = new StreamSocketListener(); await _defaultEndpointSocket.BindServiceNameAsync(options.GetDefaultEndpointPort().ToString(), SocketProtectionLevel.PlainSocket); _defaultEndpointSocket.ConnectionReceived += AcceptDefaultEndpointConnectionsAsync; } if (options.TlsEndpointOptions.IsEnabled) { throw new NotSupportedException("TLS servers are not supported for UWP apps."); } } public Task StopAsync() { _defaultEndpointSocket?.Dispose(); _defaultEndpointSocket = null; return Task.FromResult(0); } public void Dispose() { StopAsync(); } private void AcceptDefaultEndpointConnectionsAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { try { var clientAdapter = _mqttCommunicationAdapterFactory.CreateServerMqttCommunicationAdapter(new MqttTcpChannel(args.Socket)); ClientAccepted?.Invoke(this, new MqttServerAdapterClientAcceptedEventArgs(clientAdapter)); } catch (Exception exception) { _logger.LogError(new EventId(), exception, "Error while accepting connection at default endpoint."); } } } }