mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-26 08:02:59 +08:00
1908 support unix domain sockets (#1919)
* Add support for custom endpoints Add overlaods etc. to allow for passing other endpoint implementations * Extend publich broker test to also probe with different protocol versions * Fix UWP build * Update ReleaseNotes.md
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Packets;
|
||||
@@ -22,7 +23,9 @@ namespace MQTTnet.Client
|
||||
|
||||
MqttClientTcpOptions _tcpOptions;
|
||||
MqttClientTlsOptions _tlsOptions;
|
||||
|
||||
EndPoint _remoteEndPoint;
|
||||
int? _port;
|
||||
|
||||
[Obsolete] MqttClientOptionsBuilderTlsParameters _tlsParameters;
|
||||
|
||||
MqttClientWebSocketOptions _webSocketOptions;
|
||||
@@ -63,6 +66,31 @@ namespace MQTTnet.Client
|
||||
if (_tcpOptions != null)
|
||||
{
|
||||
_tcpOptions.TlsOptions = tlsOptions;
|
||||
|
||||
if (_remoteEndPoint == null)
|
||||
{
|
||||
throw new ArgumentException("No endpoint is set.");
|
||||
}
|
||||
|
||||
if (_remoteEndPoint is DnsEndPoint dns)
|
||||
{
|
||||
if (dns.Port == 0)
|
||||
{
|
||||
if (_port.HasValue)
|
||||
{
|
||||
_remoteEndPoint = new DnsEndPoint(dns.Host, _port.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_remoteEndPoint = new DnsEndPoint(dns.Host, tlsOptions?.UseTls == false ? MqttPorts.Default : MqttPorts.Secure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_tcpOptions.RemoteEndpoint == null)
|
||||
{
|
||||
_tcpOptions.RemoteEndpoint = _remoteEndPoint;
|
||||
}
|
||||
}
|
||||
else if (_webSocketOptions != null)
|
||||
{
|
||||
@@ -307,11 +335,20 @@ namespace MQTTnet.Client
|
||||
|
||||
public MqttClientOptionsBuilder WithTcpServer(string server, int? port = null)
|
||||
{
|
||||
_tcpOptions = new MqttClientTcpOptions
|
||||
{
|
||||
Server = server,
|
||||
Port = port
|
||||
};
|
||||
_tcpOptions = new MqttClientTcpOptions();
|
||||
|
||||
// The value 0 will be updated when building the options.
|
||||
// This a backward compatibility feature.
|
||||
_remoteEndPoint = new DnsEndPoint(server, port ?? 0);
|
||||
_port = port;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttClientOptionsBuilder WithEndPoint(EndPoint endPoint)
|
||||
{
|
||||
_remoteEndPoint = endPoint ?? throw new ArgumentNullException(nameof(endPoint));
|
||||
_tcpOptions = new MqttClientTcpOptions();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -11,34 +11,32 @@ namespace MQTTnet.Client
|
||||
{
|
||||
public AddressFamily AddressFamily { get; set; } = AddressFamily.Unspecified;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the local endpoint (network card) which is used by the client.
|
||||
/// Set it to _null_ to let the OS select the network card.
|
||||
/// </summary>
|
||||
public EndPoint LocalEndpoint { get; set; }
|
||||
|
||||
public int BufferSize { get; set; } = 8192;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the underlying socket should run in dual mode.
|
||||
/// Leaving this _null_ will avoid setting this value at socket level.
|
||||
/// Setting this a value other than _null_ will throw an exception when only IPv4 is supported on the machine.
|
||||
/// Gets or sets whether the underlying socket should run in dual mode.
|
||||
/// Leaving this _null_ will avoid setting this value at socket level.
|
||||
/// Setting this a value other than _null_ will throw an exception when only IPv4 is supported on the machine.
|
||||
/// </summary>
|
||||
public bool? DualMode { get; set; }
|
||||
|
||||
public LingerOption LingerState { get; set; } = new LingerOption(true, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the local endpoint (network card) which is used by the client.
|
||||
/// Set it to _null_ to let the OS select the network card.
|
||||
/// </summary>
|
||||
public EndPoint LocalEndpoint { get; set; }
|
||||
|
||||
public bool NoDelay { get; set; } = true;
|
||||
|
||||
public int? Port { get; set; }
|
||||
|
||||
public string Server { get; set; }
|
||||
public EndPoint RemoteEndpoint { get; set; }
|
||||
|
||||
public MqttClientTlsOptions TlsOptions { get; set; } = new MqttClientTlsOptions();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Server + ":" + this.GetPort();
|
||||
return RemoteEndpoint?.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace MQTTnet.Client
|
||||
{
|
||||
public static class MqttClientTcpOptionsExtensions
|
||||
{
|
||||
public static int GetPort(this MqttClientTcpOptions options)
|
||||
{
|
||||
if (options == null) throw new ArgumentNullException(nameof(options));
|
||||
|
||||
if (options.Port.HasValue)
|
||||
{
|
||||
return options.Port.Value;
|
||||
}
|
||||
|
||||
return !(options.TlsOptions?.UseTls ?? false) ? 1883 : 8883;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,11 +170,16 @@ namespace MQTTnet.Implementations
|
||||
_socket.Bind(localEndPoint);
|
||||
}
|
||||
|
||||
public async Task ConnectAsync(string host, int port, CancellationToken cancellationToken)
|
||||
public Task ConnectAsync(string host, int port, CancellationToken cancellationToken)
|
||||
{
|
||||
if (host is null)
|
||||
return ConnectAsync(new DnsEndPoint(host, port), cancellationToken);
|
||||
}
|
||||
|
||||
public async Task ConnectAsync(EndPoint endPoint, CancellationToken cancellationToken)
|
||||
{
|
||||
if (endPoint is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(host));
|
||||
throw new ArgumentNullException(nameof(endPoint));
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -191,15 +196,15 @@ namespace MQTTnet.Implementations
|
||||
#endif
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
await _socket.ConnectAsync(host, port, cancellationToken).ConfigureAwait(false);
|
||||
await _socket.ConnectAsync(endPoint, cancellationToken).ConfigureAwait(false);
|
||||
#else
|
||||
// Workaround for: https://github.com/dotnet/corefx/issues/24430
|
||||
using (cancellationToken.Register(_socketDisposeAction))
|
||||
{
|
||||
#if NET452 || NET461
|
||||
await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, host, port, null).ConfigureAwait(false);
|
||||
await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, endPoint, null).ConfigureAwait(false);
|
||||
#else
|
||||
await _socket.ConnectAsync(host, port).ConfigureAwait(false);
|
||||
await _socket.ConnectAsync(endPoint).ConfigureAwait(false);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -217,7 +222,7 @@ namespace MQTTnet.Implementations
|
||||
throw new MqttCommunicationTimedOutException();
|
||||
}
|
||||
|
||||
throw new MqttCommunicationException($"Error while connecting with host '{host}:{port}'.", socketException);
|
||||
throw new MqttCommunicationException($"Error while connecting host '{endPoint}'.", socketException);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ using MQTTnet.Channel;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Server;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Net;
|
||||
|
||||
namespace MQTTnet.Implementations
|
||||
{
|
||||
@@ -65,9 +66,22 @@ namespace MQTTnet.Implementations
|
||||
_socket.Control.KeepAlive = true;
|
||||
}
|
||||
|
||||
string hostName;
|
||||
string serviceName;
|
||||
|
||||
if (_options.RemoteEndpoint is DnsEndPoint dns)
|
||||
{
|
||||
hostName = dns.Host;
|
||||
serviceName = dns.Port.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("UWP only supports a DNS endpoint.");
|
||||
}
|
||||
|
||||
if (_options.TlsOptions?.UseTls != true)
|
||||
{
|
||||
await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString()).AsTask().ConfigureAwait(false);
|
||||
await _socket.ConnectAsync(new HostName(hostName), serviceName).AsTask().ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -88,7 +102,7 @@ namespace MQTTnet.Implementations
|
||||
socketProtectionLevel = SocketProtectionLevel.Tls10;
|
||||
}
|
||||
|
||||
await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString(), socketProtectionLevel).AsTask().ConfigureAwait(false);
|
||||
await _socket.ConnectAsync(new HostName(hostName), serviceName, socketProtectionLevel).AsTask().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#if !WINDOWS_UWP
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.ExceptionServices;
|
||||
@@ -92,7 +93,7 @@ namespace MQTTnet.Implementations
|
||||
socket.DualMode = _tcpOptions.DualMode.Value;
|
||||
}
|
||||
|
||||
await socket.ConnectAsync(_tcpOptions.Server, _tcpOptions.GetPort(), cancellationToken).ConfigureAwait(false);
|
||||
await socket.ConnectAsync(_tcpOptions.RemoteEndpoint, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
@@ -103,9 +104,11 @@ namespace MQTTnet.Implementations
|
||||
var targetHost = _tcpOptions.TlsOptions.TargetHost;
|
||||
if (string.IsNullOrEmpty(targetHost))
|
||||
{
|
||||
targetHost = _tcpOptions.Server;
|
||||
if (_tcpOptions.RemoteEndpoint is DnsEndPoint dns)
|
||||
{
|
||||
targetHost = dns.Host;
|
||||
}
|
||||
}
|
||||
|
||||
var sslStream = new SslStream(networkStream, false, InternalUserCertificateValidationCallback);
|
||||
try
|
||||
{
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace MQTTnet.Protocol
|
||||
{
|
||||
public static class MqttPorts
|
||||
{
|
||||
public const int Default = 1883;
|
||||
|
||||
public const int Secure = 8883;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user