diff --git a/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj b/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj
index a76986e1..b8edf8ae 100644
--- a/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj
+++ b/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj
@@ -19,7 +19,11 @@
-
+
+
+
+
+
diff --git a/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs b/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs
index 4aa0446a..47efc013 100644
--- a/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs
+++ b/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs
@@ -11,11 +11,18 @@ using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.AspNetCore.Extensions;
+using MQTTnet.Internal;
namespace MQTTnet.AspNetCore
{
- public class MqttConnectionContext : IMqttChannelAdapter
+ public sealed class MqttConnectionContext : IMqttChannelAdapter
{
+ readonly AsyncLock _writerLock = new AsyncLock();
+ readonly SpanBasedMqttPacketBodyReader _reader;
+
+ PipeReader _input;
+ PipeWriter _output;
+
public MqttConnectionContext(MqttPacketFormatterAdapter packetFormatterAdapter, ConnectionContext connection)
{
PacketFormatterAdapter = packetFormatterAdapter ?? throw new ArgumentNullException(nameof(packetFormatterAdapter));
@@ -30,10 +37,6 @@ namespace MQTTnet.AspNetCore
_reader = new SpanBasedMqttPacketBodyReader();
}
- private PipeReader _input;
- private PipeWriter _output;
- private readonly SpanBasedMqttPacketBodyReader _reader;
-
public string Endpoint
{
get
@@ -58,9 +61,8 @@ namespace MQTTnet.AspNetCore
public X509Certificate2 ClientCertificate => Http?.HttpContext?.Connection?.ClientCertificate;
- private IHttpContextFeature Http => Connection.Features.Get();
-
public ConnectionContext Connection { get; }
+
public MqttPacketFormatterAdapter PacketFormatterAdapter { get; }
public long BytesSent { get; set; }
@@ -69,7 +71,7 @@ namespace MQTTnet.AspNetCore
public Action ReadingPacketStartedCallback { get; set; }
public Action ReadingPacketCompletedCallback { get; set; }
- private readonly SemaphoreSlim _writerSemaphore = new SemaphoreSlim(1, 1);
+ IHttpContextFeature Http => Connection.Features.Get();
public async Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken)
{
@@ -165,8 +167,7 @@ namespace MQTTnet.AspNetCore
var msg = buffer.AsMemory();
var output = _output;
- await _writerSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
- try
+ using (await _writerLock.WaitAsync(cancellationToken).ConfigureAwait(false))
{
var result = await output.WriteAsync(msg, cancellationToken).ConfigureAwait(false);
if (result.IsCompleted)
@@ -176,10 +177,6 @@ namespace MQTTnet.AspNetCore
PacketFormatterAdapter.FreeBuffer();
}
- finally
- {
- _writerSemaphore.Release();
- }
}
public void Dispose()
diff --git a/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs b/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs
index d400ab3d..6386b4fe 100644
--- a/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs
+++ b/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs
@@ -1,12 +1,29 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
+using Microsoft.AspNetCore.Http;
namespace MQTTnet.AspNetCore
{
public static class MqttSubProtocolSelector
{
+ public static string SelectSubProtocol(HttpRequest request)
+ {
+ if (request == null) throw new ArgumentNullException(nameof(request));
+
+ string subProtocol = null;
+ if (request.Headers.TryGetValue("Sec-WebSocket-Protocol", out var requestedSubProtocolValues))
+ {
+ subProtocol = SelectSubProtocol(requestedSubProtocolValues);
+ }
+
+ return subProtocol;
+ }
+
public static string SelectSubProtocol(IList requestedSubProtocolValues)
{
+ if (requestedSubProtocolValues == null) throw new ArgumentNullException(nameof(requestedSubProtocolValues));
+
// Order the protocols to also match "mqtt", "mqttv-3.1", "mqttv-3.11" etc.
return requestedSubProtocolValues
.OrderByDescending(p => p.Length)
diff --git a/Source/MQTTnet.Server/MQTTnet.Server.csproj b/Source/MQTTnet.Server/MQTTnet.Server.csproj
index 8f2ac2ef..4f07a09d 100644
--- a/Source/MQTTnet.Server/MQTTnet.Server.csproj
+++ b/Source/MQTTnet.Server/MQTTnet.Server.csproj
@@ -39,12 +39,12 @@
-
-
-
+
+
+
-
-
+
+
diff --git a/Source/MQTTnet/Client/IMqttClientFactory.cs b/Source/MQTTnet/Client/IMqttClientFactory.cs
index bae75aca..b256e742 100644
--- a/Source/MQTTnet/Client/IMqttClientFactory.cs
+++ b/Source/MQTTnet/Client/IMqttClientFactory.cs
@@ -1,5 +1,7 @@
-using MQTTnet.Adapter;
+using System;
+using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
+using MQTTnet.LowLevelClient;
namespace MQTTnet.Client
{
@@ -7,6 +9,14 @@ namespace MQTTnet.Client
{
IMqttFactory UseClientAdapterFactory(IMqttClientAdapterFactory clientAdapterFactory);
+ ILowLevelMqttClient CreateLowLevelMqttClient();
+
+ ILowLevelMqttClient CreateLowLevelMqttClient(IMqttNetLogger logger);
+
+ ILowLevelMqttClient CreateLowLevelMqttClient(IMqttClientAdapterFactory clientAdapterFactory);
+
+ ILowLevelMqttClient CreateLowLevelMqttClient(IMqttNetLogger logger, IMqttClientAdapterFactory clientAdapterFactory);
+
IMqttClient CreateMqttClient();
IMqttClient CreateMqttClient(IMqttNetLogger logger);
diff --git a/Source/MQTTnet/IMqttFactory.cs b/Source/MQTTnet/IMqttFactory.cs
index 487d77f4..8c0e5af3 100644
--- a/Source/MQTTnet/IMqttFactory.cs
+++ b/Source/MQTTnet/IMqttFactory.cs
@@ -1,4 +1,5 @@
-using MQTTnet.Client;
+using System.Collections.Generic;
+using MQTTnet.Client;
using MQTTnet.Diagnostics;
using MQTTnet.Server;
@@ -7,5 +8,7 @@ namespace MQTTnet
public interface IMqttFactory : IMqttClientFactory, IMqttServerFactory
{
IMqttNetLogger DefaultLogger { get; }
+
+ IDictionary