mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-19 19:13:11 +08:00
migrate uwp platform to netstandard project
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
#if NET451 || NETSTANDARD1_3
|
||||
#else
|
||||
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<MqttServerAdapter> _logger;
|
||||
private readonly IMqttCommunicationAdapterFactory _mqttCommunicationAdapterFactory;
|
||||
private StreamSocketListener _defaultEndpointSocket;
|
||||
|
||||
public MqttServerAdapter(ILogger<MqttServerAdapter> logger, IMqttCommunicationAdapterFactory mqttCommunicationAdapterFactory)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_mqttCommunicationAdapterFactory = mqttCommunicationAdapterFactory ?? throw new ArgumentNullException(nameof(mqttCommunicationAdapterFactory));
|
||||
}
|
||||
|
||||
public event EventHandler<MqttServerAdapterClientAcceptedEventArgs> 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();
|
||||
_defaultEndpointSocket.Control.NoDelay = true;
|
||||
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
|
||||
{
|
||||
args.Socket.Control.NoDelay = true;
|
||||
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,139 @@
|
||||
#if NET451 || NETSTANDARD1_3
|
||||
#else
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Networking;
|
||||
using Windows.Networking.Sockets;
|
||||
using Windows.Security.Cryptography.Certificates;
|
||||
using MQTTnet.Core.Channel;
|
||||
using MQTTnet.Core.Client;
|
||||
|
||||
namespace MQTTnet.Implementations
|
||||
{
|
||||
public sealed class MqttTcpChannel : IMqttCommunicationChannel, IDisposable
|
||||
{
|
||||
private readonly MqttClientTcpOptions _options;
|
||||
private StreamSocket _socket;
|
||||
|
||||
public MqttTcpChannel(MqttClientTcpOptions options)
|
||||
{
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
public MqttTcpChannel(StreamSocket socket)
|
||||
{
|
||||
_socket = socket ?? throw new ArgumentNullException(nameof(socket));
|
||||
|
||||
CreateStreams();
|
||||
}
|
||||
|
||||
public Stream SendStream { get; private set; }
|
||||
public Stream ReceiveStream { get; private set; }
|
||||
public Stream RawReceiveStream { get; private set; }
|
||||
|
||||
public static Func<MqttClientTcpOptions, IEnumerable<ChainValidationResult>> CustomIgnorableServerCertificateErrorsResolver { get; set; }
|
||||
|
||||
public async Task ConnectAsync()
|
||||
{
|
||||
if (_socket == null)
|
||||
{
|
||||
_socket = new StreamSocket();
|
||||
}
|
||||
|
||||
if (!_options.TlsOptions.UseTls)
|
||||
{
|
||||
await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
_socket.Control.ClientCertificate = LoadCertificate(_options);
|
||||
|
||||
foreach (var ignorableChainValidationResult in ResolveIgnorableServerCertificateErrors())
|
||||
{
|
||||
_socket.Control.IgnorableServerCertificateErrors.Add(ignorableChainValidationResult);
|
||||
}
|
||||
|
||||
await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString(), SocketProtectionLevel.Tls12);
|
||||
}
|
||||
|
||||
CreateStreams();
|
||||
}
|
||||
|
||||
public Task DisconnectAsync()
|
||||
{
|
||||
Dispose();
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
RawReceiveStream?.Dispose();
|
||||
RawReceiveStream = null;
|
||||
|
||||
SendStream?.Dispose();
|
||||
SendStream = null;
|
||||
|
||||
ReceiveStream?.Dispose();
|
||||
ReceiveStream = null;
|
||||
|
||||
_socket?.Dispose();
|
||||
_socket = null;
|
||||
}
|
||||
|
||||
private void CreateStreams()
|
||||
{
|
||||
SendStream = _socket.OutputStream.AsStreamForWrite();
|
||||
ReceiveStream = _socket.InputStream.AsStreamForRead();
|
||||
RawReceiveStream = ReceiveStream;
|
||||
}
|
||||
|
||||
private static Certificate LoadCertificate(MqttClientTcpOptions options)
|
||||
{
|
||||
if (options.TlsOptions.Certificates == null || !options.TlsOptions.Certificates.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (options.TlsOptions.Certificates.Count > 1)
|
||||
{
|
||||
throw new NotSupportedException("Only one client certificate is supported for UWP.");
|
||||
}
|
||||
|
||||
return new Certificate(options.TlsOptions.Certificates.First().AsBuffer());
|
||||
}
|
||||
|
||||
private IEnumerable<ChainValidationResult> ResolveIgnorableServerCertificateErrors()
|
||||
{
|
||||
if (CustomIgnorableServerCertificateErrorsResolver != null)
|
||||
{
|
||||
return CustomIgnorableServerCertificateErrorsResolver(_options);
|
||||
}
|
||||
|
||||
var result = new List<ChainValidationResult>();
|
||||
|
||||
if (_options.TlsOptions.IgnoreCertificateRevocationErrors)
|
||||
{
|
||||
result.Add(ChainValidationResult.RevocationInformationMissing);
|
||||
//_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Revoked); Not supported.
|
||||
result.Add(ChainValidationResult.RevocationFailure);
|
||||
}
|
||||
|
||||
if (_options.TlsOptions.IgnoreCertificateChainErrors)
|
||||
{
|
||||
result.Add(ChainValidationResult.IncompleteChain);
|
||||
}
|
||||
|
||||
if (_options.TlsOptions.AllowUntrustedCertificates)
|
||||
{
|
||||
result.Add(ChainValidationResult.Untrusted);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user