diff --git a/.github/workflows/ReleaseNotes.md b/.github/workflows/ReleaseNotes.md
index e04b0b0d..ff28cadd 100644
--- a/.github/workflows/ReleaseNotes.md
+++ b/.github/workflows/ReleaseNotes.md
@@ -1,3 +1,4 @@
+* [Client] Exposed the _EndPoint_ type to support other endpoint types (like Unix Domain Sockets) in client options (#1919).
* [Server] Added new events for delivered and dropped messages (#1866, thanks to @kallayj).
* [Server] The server will no longer treat a client which is receiving a large payload as alive. The packet must be received completely within the keep alive boundaries (BREAKING CHANGE!, #1883).
* [Server] Fixed "service not registered" exception in ASP.NET integration (#1889).
diff --git a/MQTTnet.sln.DotSettings b/MQTTnet.sln.DotSettings
index 813b5520..b12b2985 100644
--- a/MQTTnet.sln.DotSettings
+++ b/MQTTnet.sln.DotSettings
@@ -230,6 +230,7 @@
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.
+ True
True
True
True
diff --git a/Source/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs b/Source/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs
index e24074d4..003e6190 100644
--- a/Source/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs
+++ b/Source/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs
@@ -48,7 +48,6 @@ namespace MQTTnet.AspNetCore.Tests
{
var mockup = new ConnectionHandlerMockup();
-
using (var host = new WebHostBuilder().UseKestrel(kestrel => kestrel.ListenLocalhost(1883, listener => listener.Use((ctx, next) => mockup.OnConnectedAsync(ctx))))
.UseStartup()
.ConfigureServices(
diff --git a/Source/MQTTnet.AspnetCore/Client/MqttClientConnectionContextFactory.cs b/Source/MQTTnet.AspnetCore/Client/MqttClientConnectionContextFactory.cs
index f8e38f4e..7afd3e21 100644
--- a/Source/MQTTnet.AspnetCore/Client/MqttClientConnectionContextFactory.cs
+++ b/Source/MQTTnet.AspnetCore/Client/MqttClientConnectionContextFactory.cs
@@ -6,7 +6,6 @@ using MQTTnet.Adapter;
using MQTTnet.AspNetCore.Client.Tcp;
using MQTTnet.Formatter;
using System;
-using System.Net;
using MQTTnet.Client;
using MQTTnet.Diagnostics;
@@ -22,8 +21,7 @@ namespace MQTTnet.AspNetCore.Client
{
case MqttClientTcpOptions tcpOptions:
{
- var endpoint = new DnsEndPoint(tcpOptions.Server, tcpOptions.GetPort());
- var tcpConnection = new TcpConnection(endpoint);
+ var tcpConnection = new SocketConnection(tcpOptions.RemoteEndpoint);
var formatter = new MqttPacketFormatterAdapter(options.ProtocolVersion, new MqttBufferWriter(4096, 65535));
return new MqttConnectionContext(formatter, tcpConnection);
diff --git a/Source/MQTTnet.AspnetCore/Client/Tcp/TcpConnection.cs b/Source/MQTTnet.AspnetCore/Client/Tcp/SocketConnection.cs
similarity index 91%
rename from Source/MQTTnet.AspnetCore/Client/Tcp/TcpConnection.cs
rename to Source/MQTTnet.AspnetCore/Client/Tcp/SocketConnection.cs
index c3a6227a..8fb19914 100644
--- a/Source/MQTTnet.AspnetCore/Client/Tcp/TcpConnection.cs
+++ b/Source/MQTTnet.AspnetCore/Client/Tcp/SocketConnection.cs
@@ -15,15 +15,15 @@ using System.Threading.Tasks;
namespace MQTTnet.AspNetCore.Client.Tcp
{
- public class TcpConnection : ConnectionContext
+ public sealed class SocketConnection : ConnectionContext
{
- private volatile bool _aborted;
- private readonly EndPoint _endPoint;
- private SocketSender _sender;
- private SocketReceiver _receiver;
+ volatile bool _aborted;
+ readonly EndPoint _endPoint;
+ SocketSender _sender;
+ SocketReceiver _receiver;
- private Socket _socket;
- private IDuplexPipe _application;
+ Socket _socket;
+ IDuplexPipe _application;
public bool IsConnected { get; private set; }
public override string ConnectionId { get; set; }
@@ -31,12 +31,12 @@ namespace MQTTnet.AspNetCore.Client.Tcp
public override IDictionary Items { get; set; }
public override IDuplexPipe Transport { get; set; }
- public TcpConnection(EndPoint endPoint)
+ public SocketConnection(EndPoint endPoint)
{
_endPoint = endPoint;
}
- public TcpConnection(Socket socket)
+ public SocketConnection(Socket socket)
{
_socket = socket;
_endPoint = socket.RemoteEndPoint;
@@ -87,7 +87,7 @@ namespace MQTTnet.AspNetCore.Client.Tcp
IsConnected = true;
}
- private async Task ExecuteAsync()
+ async Task ExecuteAsync()
{
Exception sendError = null;
try
@@ -114,7 +114,7 @@ namespace MQTTnet.AspNetCore.Client.Tcp
}
catch (Exception ex)
{
- Console.WriteLine($"Unexpected exception in {nameof(TcpConnection)}.{nameof(StartAsync)}: " + ex);
+ Console.WriteLine($"Unexpected exception in {nameof(SocketConnection)}.{nameof(StartAsync)}: " + ex);
}
finally
{
@@ -122,7 +122,8 @@ namespace MQTTnet.AspNetCore.Client.Tcp
_application.Input.Complete(sendError);
}
}
- private async Task DoReceive()
+
+ async Task DoReceive()
{
Exception error = null;
@@ -171,7 +172,7 @@ namespace MQTTnet.AspNetCore.Client.Tcp
}
}
- private async Task ProcessReceives()
+ async Task ProcessReceives()
{
while (true)
{
@@ -204,12 +205,12 @@ namespace MQTTnet.AspNetCore.Client.Tcp
}
}
- private Exception ConnectionAborted()
+ Exception ConnectionAborted()
{
return new MqttCommunicationException("Connection Aborted");
}
- private async Task DoSend()
+ async Task DoSend()
{
Exception error = null;
@@ -240,7 +241,7 @@ namespace MQTTnet.AspNetCore.Client.Tcp
return error;
}
- private async Task ProcessSends()
+ async Task ProcessSends()
{
while (true)
{
diff --git a/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs b/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs
index 8638af6f..da0a1824 100644
--- a/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs
+++ b/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs
@@ -33,7 +33,7 @@ namespace MQTTnet.AspNetCore
PacketFormatterAdapter = packetFormatterAdapter ?? throw new ArgumentNullException(nameof(packetFormatterAdapter));
_connection = connection ?? throw new ArgumentNullException(nameof(connection));
- if (!(_connection is TcpConnection tcp) || tcp.IsConnected)
+ if (!(_connection is SocketConnection tcp) || tcp.IsConnected)
{
_input = connection.Transport.Input;
_output = connection.Transport.Output;
@@ -109,7 +109,7 @@ namespace MQTTnet.AspNetCore
public async Task ConnectAsync(CancellationToken cancellationToken)
{
- if (_connection is TcpConnection tcp && !tcp.IsConnected)
+ if (_connection is SocketConnection tcp && !tcp.IsConnected)
{
await tcp.StartAsync().ConfigureAwait(false);
}
diff --git a/Source/MQTTnet.Benchmarks/TcpPipesBenchmark.cs b/Source/MQTTnet.Benchmarks/TcpPipesBenchmark.cs
index cc84f379..32e45a3a 100644
--- a/Source/MQTTnet.Benchmarks/TcpPipesBenchmark.cs
+++ b/Source/MQTTnet.Benchmarks/TcpPipesBenchmark.cs
@@ -29,12 +29,12 @@ namespace MQTTnet.Benchmarks
var task = Task.Run(() => server.AcceptSocket());
- var clientConnection = new TcpConnection(new IPEndPoint(IPAddress.Loopback, 1883));
+ var clientConnection = new SocketConnection(new IPEndPoint(IPAddress.Loopback, 1883));
clientConnection.StartAsync().GetAwaiter().GetResult();
_client = clientConnection.Transport;
- var serverConnection = new TcpConnection(task.GetAwaiter().GetResult());
+ var serverConnection = new SocketConnection(task.GetAwaiter().GetResult());
serverConnection.StartAsync().GetAwaiter().GetResult();
_server = serverConnection.Transport;
}
diff --git a/Source/MQTTnet.TestApp/ClientTest.cs b/Source/MQTTnet.TestApp/ClientTest.cs
index 274515fa..15634fdf 100644
--- a/Source/MQTTnet.TestApp/ClientTest.cs
+++ b/Source/MQTTnet.TestApp/ClientTest.cs
@@ -4,6 +4,7 @@
using MQTTnet.Client;
using System;
+using System.Net;
using System.Text;
using System.Threading.Tasks;
using MQTTnet.Diagnostics;
@@ -27,7 +28,7 @@ namespace MQTTnet.TestApp
{
ChannelOptions = new MqttClientTcpOptions
{
- Server = "127.0.0.1"
+ RemoteEndpoint = new DnsEndPoint("127.0.0.1", 0)
}
};
diff --git a/Source/MQTTnet.TestApp/MQTTnet.TestApp.csproj b/Source/MQTTnet.TestApp/MQTTnet.TestApp.csproj
index ef336f45..93973e70 100644
--- a/Source/MQTTnet.TestApp/MQTTnet.TestApp.csproj
+++ b/Source/MQTTnet.TestApp/MQTTnet.TestApp.csproj
@@ -10,6 +10,7 @@
false
true
1591;NETSDK1138
+ 7.3
diff --git a/Source/MQTTnet.TestApp/ManagedClientTest.cs b/Source/MQTTnet.TestApp/ManagedClientTest.cs
index 976c17e6..0c51a818 100644
--- a/Source/MQTTnet.TestApp/ManagedClientTest.cs
+++ b/Source/MQTTnet.TestApp/ManagedClientTest.cs
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
using System.Collections.Generic;
+using System.Net;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Internal;
@@ -28,7 +29,7 @@ namespace MQTTnet.TestApp
Credentials = new RandomPassword(),
ChannelOptions = new MqttClientTcpOptions
{
- Server = "broker.hivemq.com"
+ RemoteEndpoint = new DnsEndPoint("broker.hivemq.com", 0)
}
},
diff --git a/Source/MQTTnet.TestApp/PerformanceTest.cs b/Source/MQTTnet.TestApp/PerformanceTest.cs
index c1bd991e..16f5ba25 100644
--- a/Source/MQTTnet.TestApp/PerformanceTest.cs
+++ b/Source/MQTTnet.TestApp/PerformanceTest.cs
@@ -5,13 +5,13 @@
using System;
using System.Diagnostics;
using System.Linq;
+using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Client;
using MQTTnet.Protocol;
using MQTTnet.Server;
-using MqttClient = MQTTnet.Client.MqttClient;
namespace MQTTnet.TestApp
{
@@ -25,7 +25,7 @@ namespace MQTTnet.TestApp
{
ChannelOptions = new MqttClientTcpOptions
{
- Server = "127.0.0.1"
+ RemoteEndpoint = new DnsEndPoint("127.0.0.1", 0)
},
CleanSession = true
};
@@ -71,7 +71,7 @@ namespace MQTTnet.TestApp
{
ChannelOptions = new MqttClientTcpOptions
{
- Server = "127.0.0.1"
+ RemoteEndpoint = new DnsEndPoint("127.0.0.1", 0)
}
};
@@ -114,7 +114,10 @@ namespace MQTTnet.TestApp
{
var options = new MqttClientOptions
{
- ChannelOptions = new MqttClientTcpOptions { Server = "localhost" },
+ ChannelOptions = new MqttClientTcpOptions
+ {
+ RemoteEndpoint = new DnsEndPoint("localhost", 0)
+ },
ClientId = "Client1",
CleanSession = true
};
@@ -218,7 +221,7 @@ namespace MQTTnet.TestApp
{
ChannelOptions = new MqttClientTcpOptions
{
- Server = "127.0.0.1"
+ RemoteEndpoint = new DnsEndPoint("127.0.0.1", 0)
},
CleanSession = true
};
@@ -269,7 +272,7 @@ namespace MQTTnet.TestApp
{
ChannelOptions = new MqttClientTcpOptions
{
- Server = "127.0.0.1"
+ RemoteEndpoint = new DnsEndPoint("127.0.0.1", 0)
},
CleanSession = true
};
@@ -320,7 +323,7 @@ namespace MQTTnet.TestApp
{
ChannelOptions = new MqttClientTcpOptions
{
- Server = "127.0.0.1"
+ RemoteEndpoint = new DnsEndPoint("127.0.0.1", 0)
},
CleanSession = true
};
diff --git a/Source/MQTTnet.TestApp/PublicBrokerTest.cs b/Source/MQTTnet.TestApp/PublicBrokerTest.cs
index b43b00ef..5e38a0e6 100644
--- a/Source/MQTTnet.TestApp/PublicBrokerTest.cs
+++ b/Source/MQTTnet.TestApp/PublicBrokerTest.cs
@@ -42,45 +42,45 @@ namespace MQTTnet.TestApp
};
// mqtt.eclipseprojects.io
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"mqtt.eclipseprojects.io TCP",
new MqttClientOptionsBuilder().WithTcpServer("mqtt.eclipseprojects.io", 1883).WithProtocolVersion(MqttProtocolVersion.V311).Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"mqtt.eclipseprojects.io WS",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("mqtt.eclipseprojects.io:80/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).Build());
#if NET5_0_OR_GREATER
- await ExecuteTestAsync("mqtt.eclipseprojects.io WS TLS13",
+ await ExecuteTestsAsync("mqtt.eclipseprojects.io WS TLS13",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("mqtt.eclipseprojects.io:443/mqtt"))
.WithProtocolVersion(MqttProtocolVersion.V311).WithTlsOptions(unsafeTls13).Build());
- await ExecuteTestAsync("mqtt.eclipseprojects.io WS TLS13 (WebSocket4Net)",
+ await ExecuteTestsAsync("mqtt.eclipseprojects.io WS TLS13 (WebSocket4Net)",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("mqtt.eclipseprojects.io:443/mqtt"))
.WithProtocolVersion(MqttProtocolVersion.V311).WithTlsOptions(unsafeTls13).Build(),
true);
#endif
// test.mosquitto.org
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"test.mosquitto.org TCP",
new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 1883).WithProtocolVersion(MqttProtocolVersion.V311).Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"test.mosquitto.org TCP - Authenticated",
new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 1884).WithCredentials("rw", "readwrite").WithProtocolVersion(MqttProtocolVersion.V311).Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"test.mosquitto.org TCP TLS12",
new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 8883).WithProtocolVersion(MqttProtocolVersion.V311).WithTlsOptions(unsafeTls12).Build());
#if NET5_0_OR_GREATER
- await ExecuteTestAsync("test.mosquitto.org TCP TLS13",
+ await ExecuteTestsAsync("test.mosquitto.org TCP TLS13",
new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 8883)
.WithProtocolVersion(MqttProtocolVersion.V311).WithTlsOptions(unsafeTls13).Build());
#endif
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"test.mosquitto.org TCP TLS12 - Authenticated",
new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 8885)
.WithCredentials("rw", "readwrite")
@@ -88,67 +88,67 @@ namespace MQTTnet.TestApp
.WithTlsOptions(unsafeTls12)
.Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"test.mosquitto.org WS",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("test.mosquitto.org:8080/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"test.mosquitto.org WS (WebSocket4Net)",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("test.mosquitto.org:8080/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).Build(),
true);
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"test.mosquitto.org WS TLS12",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("test.mosquitto.org:8081/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).WithTlsOptions(unsafeTls12).Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"test.mosquitto.org WS TLS12 (WebSocket4Net)",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("test.mosquitto.org:8081/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).WithTlsOptions(unsafeTls12).Build(),
true);
// broker.emqx.io
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"broker.emqx.io TCP",
new MqttClientOptionsBuilder().WithTcpServer("broker.emqx.io", 1883).WithProtocolVersion(MqttProtocolVersion.V311).Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"broker.emqx.io TCP TLS12",
new MqttClientOptionsBuilder().WithTcpServer("broker.emqx.io", 8883).WithProtocolVersion(MqttProtocolVersion.V311).WithTlsOptions(unsafeTls12).Build());
#if NET5_0_OR_GREATER
- await ExecuteTestAsync("broker.emqx.io TCP TLS13",
+ await ExecuteTestsAsync("broker.emqx.io TCP TLS13",
new MqttClientOptionsBuilder().WithTcpServer("broker.emqx.io", 8883)
.WithProtocolVersion(MqttProtocolVersion.V311).WithTlsOptions(unsafeTls13).Build());
#endif
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"broker.emqx.io WS",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("broker.emqx.io:8083/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"broker.emqx.io WS (WebSocket4Net)",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("broker.emqx.io:8084/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).Build(),
true);
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"broker.emqx.io WS TLS12",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("broker.emqx.io:8084/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).WithTlsOptions(unsafeTls12).Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"broker.emqx.io WS TLS12 (WebSocket4Net)",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("broker.emqx.io:8084/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).WithTlsOptions(unsafeTls12).Build(),
true);
// broker.hivemq.com
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"broker.hivemq.com TCP",
new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com", 1883).WithProtocolVersion(MqttProtocolVersion.V311).Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"broker.hivemq.com WS",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("broker.hivemq.com:8000/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).Build());
- await ExecuteTestAsync(
+ await ExecuteTestsAsync(
"broker.hivemq.com WS (WebSocket4Net)",
new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("broker.hivemq.com:8000/mqtt")).WithProtocolVersion(MqttProtocolVersion.V311).Build(),
true);
@@ -160,6 +160,15 @@ namespace MQTTnet.TestApp
Console.ReadLine();
}
+ static async Task ExecuteTestsAsync(string name, MqttClientOptions options, bool useWebSocket4Net = false)
+ {
+ options.ProtocolVersion = MqttProtocolVersion.V311;
+ await ExecuteTestAsync(name + " V3.1.1", options, useWebSocket4Net);
+
+ options.ProtocolVersion = MqttProtocolVersion.V500;
+ await ExecuteTestAsync(name + " V5.0.0", options, useWebSocket4Net);
+ }
+
static async Task ExecuteTestAsync(string name, MqttClientOptions options, bool useWebSocket4Net = false)
{
try
diff --git a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs
index 2cc03a5f..b1c2ee83 100644
--- a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs
+++ b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs
@@ -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;
}
diff --git a/Source/MQTTnet/Client/Options/MqttClientTcpOptions.cs b/Source/MQTTnet/Client/Options/MqttClientTcpOptions.cs
index 586cab51..09e652b5 100644
--- a/Source/MQTTnet/Client/Options/MqttClientTcpOptions.cs
+++ b/Source/MQTTnet/Client/Options/MqttClientTcpOptions.cs
@@ -11,34 +11,32 @@ namespace MQTTnet.Client
{
public AddressFamily AddressFamily { get; set; } = AddressFamily.Unspecified;
- ///
- /// Gets the local endpoint (network card) which is used by the client.
- /// Set it to _null_ to let the OS select the network card.
- ///
- public EndPoint LocalEndpoint { get; set; }
-
public int BufferSize { get; set; } = 8192;
///
- /// 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.
///
public bool? DualMode { get; set; }
public LingerOption LingerState { get; set; } = new LingerOption(true, 0);
+ ///
+ /// Gets the local endpoint (network card) which is used by the client.
+ /// Set it to _null_ to let the OS select the network card.
+ ///
+ 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;
}
}
}
\ No newline at end of file
diff --git a/Source/MQTTnet/Client/Options/MqttClientTcpOptionsExtensions.cs b/Source/MQTTnet/Client/Options/MqttClientTcpOptionsExtensions.cs
deleted file mode 100644
index fae6bc1e..00000000
--- a/Source/MQTTnet/Client/Options/MqttClientTcpOptionsExtensions.cs
+++ /dev/null
@@ -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;
- }
- }
-}
diff --git a/Source/MQTTnet/Implementations/CrossPlatformSocket.cs b/Source/MQTTnet/Implementations/CrossPlatformSocket.cs
index ea642431..c6a8df54 100644
--- a/Source/MQTTnet/Implementations/CrossPlatformSocket.cs
+++ b/Source/MQTTnet/Implementations/CrossPlatformSocket.cs
@@ -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)
{
diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs
index d26ebe6a..d6a19865 100644
--- a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs
+++ b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs
@@ -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;
diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.cs
index f9dadf26..6ed97cca 100644
--- a/Source/MQTTnet/Implementations/MqttTcpChannel.cs
+++ b/Source/MQTTnet/Implementations/MqttTcpChannel.cs
@@ -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
{
diff --git a/Source/MQTTnet/Protocol/MqttPorts.cs b/Source/MQTTnet/Protocol/MqttPorts.cs
new file mode 100644
index 00000000..b2ea8f04
--- /dev/null
+++ b/Source/MQTTnet/Protocol/MqttPorts.cs
@@ -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;
+ }
+}
\ No newline at end of file