(this TObject @object)
12 | {
13 | var output = "NULL";
14 | if (@object != null)
15 | {
16 | output = JsonSerializer.Serialize(@object, new JsonSerializerOptions
17 | {
18 | WriteIndented = true
19 | });
20 | }
21 |
22 | Console.WriteLine($"[{@object?.GetType().Name}]:\r\n{output}");
23 | return @object;
24 | }
25 | }
--------------------------------------------------------------------------------
/Samples/MQTTnet.Samples.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 | false
9 | true
10 | false
11 | false
12 | 1591;NETSDK1138;NU1803;NU1901;NU1902
13 | true
14 | all
15 | true
16 | low
17 | latest-Recommended
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Source/MQTTnet.AspTestApp/MQTTnet.AspTestApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | false
8 | true
9 | false
10 | false
11 | 1591;NETSDK1138;NU1803;NU1901;NU1902
12 | true
13 | all
14 | true
15 | low
16 | latest-Recommended
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Source/MQTTnet.AspTestApp/Pages/Index.cshtml:
--------------------------------------------------------------------------------
1 | @page
2 | @model IndexModel
3 | @{
4 | ViewData["Title"] = "Home page";
5 | }
6 |
7 |
8 |
MQTTnet ASP.NET Core Test App
9 |
10 |
11 |
12 |
13 |
35 |
--------------------------------------------------------------------------------
/Source/MQTTnet.AspTestApp/Pages/Index.cshtml.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using Microsoft.AspNetCore.Mvc.RazorPages;
6 |
7 | namespace MQTTnet.AspTestApp.Pages;
8 |
9 | public class IndexModel : PageModel
10 | {
11 | readonly ILogger _logger;
12 |
13 | public IndexModel(ILogger logger)
14 | {
15 | _logger = logger;
16 | }
17 |
18 | public void OnGet()
19 | {
20 | _logger.LogDebug("OnGet");
21 | }
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.AspTestApp/Pages/Shared/_Layout.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @ViewData["Title"] - MQTTnet
7 |
8 |
9 |
10 | @RenderBody()
11 |
12 | @await RenderSectionAsync("Scripts", required: false)
13 |
14 |
--------------------------------------------------------------------------------
/Source/MQTTnet.AspTestApp/Pages/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @namespace MQTTnet.AspTestApp.Pages
2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
3 |
--------------------------------------------------------------------------------
/Source/MQTTnet.AspTestApp/Pages/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "_Layout";
3 | }
4 |
--------------------------------------------------------------------------------
/Source/MQTTnet.AspTestApp/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "DetailedErrors": true,
3 | "Logging": {
4 | "LogLevel": {
5 | "Default": "Information",
6 | "Microsoft.AspNetCore": "Warning"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Source/MQTTnet.AspTestApp/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "AllowedHosts": "*"
9 | }
10 |
--------------------------------------------------------------------------------
/Source/MQTTnet.AspTestApp/libman.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0",
3 | "defaultProvider": "cdnjs",
4 | "libraries": []
5 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.AspnetCore/AspNetMqttServerOptionsBuilder.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Server;
7 |
8 | namespace MQTTnet.AspNetCore;
9 |
10 | public sealed class AspNetMqttServerOptionsBuilder : MqttServerOptionsBuilder
11 | {
12 | public AspNetMqttServerOptionsBuilder(IServiceProvider serviceProvider)
13 | {
14 | ServiceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
15 | }
16 |
17 | public IServiceProvider ServiceProvider { get; }
18 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.AspnetCore/BufferExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Runtime.InteropServices;
7 |
8 | namespace MQTTnet.AspNetCore;
9 |
10 | public static class BufferExtensions
11 | {
12 | public static ArraySegment GetArray(this ReadOnlyMemory memory)
13 | {
14 | if (!MemoryMarshal.TryGetArray(memory, out var result))
15 | {
16 | throw new InvalidOperationException("Buffer backed by array was expected");
17 | }
18 |
19 | return result;
20 | }
21 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.AspnetCore/ConnectionBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using Microsoft.AspNetCore.Connections;
6 |
7 | namespace MQTTnet.AspNetCore;
8 |
9 | public static class ConnectionBuilderExtensions
10 | {
11 | public static IConnectionBuilder UseMqtt(this IConnectionBuilder builder)
12 | {
13 | return builder.UseConnectionHandler();
14 | }
15 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.AspnetCore/DuplexPipe.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.IO.Pipelines;
6 |
7 | namespace MQTTnet.AspNetCore;
8 |
9 | public class DuplexPipe : IDuplexPipe
10 | {
11 | public DuplexPipe(PipeReader reader, PipeWriter writer)
12 | {
13 | Input = reader;
14 | Output = writer;
15 | }
16 |
17 | public PipeReader Input { get; }
18 |
19 | public PipeWriter Output { get; }
20 |
21 | public static DuplexPipePair CreateConnectionPair(PipeOptions inputOptions, PipeOptions outputOptions)
22 | {
23 | var input = new Pipe(inputOptions);
24 | var output = new Pipe(outputOptions);
25 |
26 | var transportToApplication = new DuplexPipe(output.Reader, input.Writer);
27 | var applicationToTransport = new DuplexPipe(input.Reader, output.Writer);
28 |
29 | return new DuplexPipePair(applicationToTransport, transportToApplication);
30 | }
31 |
32 | // This class exists to work around issues with value tuple on .NET Framework
33 | public readonly struct DuplexPipePair
34 | {
35 | public IDuplexPipe Transport { get; }
36 | public IDuplexPipe Application { get; }
37 |
38 | public DuplexPipePair(IDuplexPipe transport, IDuplexPipe application)
39 | {
40 | Transport = transport;
41 | Application = application;
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.AspnetCore/EndpointRouterExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using Microsoft.AspNetCore.Builder;
7 | using Microsoft.AspNetCore.Routing;
8 |
9 | namespace MQTTnet.AspNetCore;
10 |
11 | public static class EndpointRouterExtensions
12 | {
13 | public static void MapMqtt(this IEndpointRouteBuilder endpoints, string pattern)
14 | {
15 | ArgumentNullException.ThrowIfNull(endpoints);
16 |
17 | endpoints.MapConnectionHandler(pattern, options =>
18 | {
19 | options.WebSockets.SubProtocolSelector = MqttSubProtocolSelector.SelectSubProtocol;
20 | });
21 | }
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.AspnetCore/MqttClientConnectionContextFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Adapter;
7 | using MQTTnet.Diagnostics.Logger;
8 | using MQTTnet.Formatter;
9 |
10 | namespace MQTTnet.AspNetCore;
11 |
12 | public sealed class MqttClientConnectionContextFactory : IMqttClientAdapterFactory
13 | {
14 | public IMqttChannelAdapter CreateClientAdapter(MqttClientOptions options, MqttPacketInspector packetInspector, IMqttNetLogger logger)
15 | {
16 | if (options == null) throw new ArgumentNullException(nameof(options));
17 |
18 | switch (options.ChannelOptions)
19 | {
20 | case MqttClientTcpOptions tcpOptions:
21 | {
22 | var tcpConnection = new SocketConnection(tcpOptions.RemoteEndpoint);
23 |
24 | var formatter = new MqttPacketFormatterAdapter(options.ProtocolVersion, new MqttBufferWriter(4096, 65535));
25 | return new MqttConnectionContext(formatter, tcpConnection);
26 | }
27 | default:
28 | {
29 | throw new NotSupportedException();
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using Microsoft.AspNetCore.Http;
9 |
10 | namespace MQTTnet.AspNetCore;
11 |
12 | public static class MqttSubProtocolSelector
13 | {
14 | public static string SelectSubProtocol(HttpRequest request)
15 | {
16 | ArgumentNullException.ThrowIfNull(request);
17 |
18 | string subProtocol = null;
19 | if (request.Headers.TryGetValue("Sec-WebSocket-Protocol", out var requestedSubProtocolValues))
20 | {
21 | subProtocol = SelectSubProtocol(requestedSubProtocolValues);
22 | }
23 |
24 | return subProtocol;
25 | }
26 |
27 | public static string SelectSubProtocol(IList requestedSubProtocolValues)
28 | {
29 | ArgumentNullException.ThrowIfNull(requestedSubProtocolValues);
30 |
31 | // Order the protocols to also match "mqtt", "mqttv-3.1", "mqttv-3.11" etc.
32 | return requestedSubProtocolValues.OrderByDescending(p => p.Length).FirstOrDefault(p => p.ToLower().StartsWith("mqtt"));
33 | }
34 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.AspnetCore/SocketReceiver.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.IO.Pipelines;
7 | using System.Net.Sockets;
8 |
9 | namespace MQTTnet.AspNetCore;
10 |
11 | public sealed class SocketReceiver
12 | {
13 | readonly SocketAwaitable _awaitable;
14 | readonly SocketAsyncEventArgs _eventArgs = new();
15 | readonly Socket _socket;
16 |
17 | public SocketReceiver(Socket socket, PipeScheduler scheduler)
18 | {
19 | _socket = socket;
20 | _awaitable = new SocketAwaitable(scheduler);
21 | _eventArgs.UserToken = _awaitable;
22 | _eventArgs.Completed += (_, e) => ((SocketAwaitable)e.UserToken).Complete(e.BytesTransferred, e.SocketError);
23 | }
24 |
25 | public SocketAwaitable ReceiveAsync(Memory buffer)
26 | {
27 | _eventArgs.SetBuffer(buffer);
28 |
29 | if (!_socket.ReceiveAsync(_eventArgs))
30 | {
31 | _awaitable.Complete(_eventArgs.BytesTransferred, _eventArgs.SocketError);
32 | }
33 |
34 | return _awaitable;
35 | }
36 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Benchmarks/BaseBenchmark.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Benchmarks;
6 |
7 | public abstract class BaseBenchmark
8 | {
9 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | Exe
6 | Full
7 | net8.0
8 | false
9 | false
10 | false
11 | true
12 | 1591;NETSDK1138;NU1803;NU1901;NU1902;CS8892
13 | false
14 | all
15 | true
16 | low
17 | latest-Recommended
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Source/MQTTnet.Benchmarks/MemoryCopyBenchmark.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Attributes;
2 | using BenchmarkDotNet.Jobs;
3 | using System;
4 |
5 |
6 | namespace MQTTnet.Benchmarks;
7 |
8 | [SimpleJob(RuntimeMoniker.Net60)]
9 | [RPlotExporter, RankColumn]
10 | [MemoryDiagnoser]
11 | public class MemoryCopyBenchmark
12 | {
13 | const int MaxLength = 1024 * 8;
14 |
15 | byte[] _source;
16 | byte[] _target;
17 |
18 | [Params(64 - 1, 128 - 1, 256 - 1, 512 - 1, 1024 - 1, 2048 - 1, 5096 - 1)]
19 | public int Length { get; set; }
20 |
21 | [GlobalSetup]
22 | public void Setup()
23 | {
24 | _source = new byte[MaxLength];
25 | _target = new byte[MaxLength];
26 | }
27 |
28 | [Benchmark(Baseline = true)]
29 | public void Array_Copy()
30 | {
31 | Array.Copy(_source, 0, _target, 0, Length);
32 | }
33 |
34 | [Benchmark]
35 | public void Memory_Copy()
36 | {
37 | Internal.MqttMemoryHelper.Copy(_source, 0, _target, 0, Length);
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Benchmarks/MessageProcessingBenchmark.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using BenchmarkDotNet.Attributes;
6 | using BenchmarkDotNet.Jobs;
7 | using MQTTnet.Server;
8 |
9 | namespace MQTTnet.Benchmarks;
10 |
11 | [SimpleJob(RuntimeMoniker.Net60)]
12 | [RPlotExporter]
13 | [RankColumn]
14 | [MemoryDiagnoser]
15 | public class MessageProcessingBenchmark : BaseBenchmark
16 | {
17 | MqttApplicationMessage _message;
18 | IMqttClient _mqttClient;
19 | MqttServer _mqttServer;
20 |
21 | [Benchmark]
22 | public void Send_10000_Messages()
23 | {
24 | for (var i = 0; i < 10000; i++)
25 | {
26 | _mqttClient.PublishAsync(_message).GetAwaiter().GetResult();
27 | }
28 | }
29 |
30 | [GlobalSetup]
31 | public void Setup()
32 | {
33 | var serverOptions = new MqttServerOptionsBuilder().Build();
34 |
35 | var serverFactory = new MqttServerFactory();
36 | _mqttServer = serverFactory.CreateMqttServer(serverOptions);
37 | var clientFactory = new MqttClientFactory();
38 | _mqttClient = clientFactory.CreateMqttClient();
39 |
40 | _mqttServer.StartAsync().GetAwaiter().GetResult();
41 |
42 | var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("localhost").Build();
43 |
44 | _mqttClient.ConnectAsync(clientOptions).GetAwaiter().GetResult();
45 |
46 | _message = new MqttApplicationMessageBuilder().WithTopic("A").Build();
47 | }
48 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Benchmarks/RoundtripProcessingBenchmark.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Attributes;
2 | using BenchmarkDotNet.Jobs;
3 | using MQTTnet.Tests.Mockups;
4 | using MQTTnet.Tests.Server;
5 |
6 | namespace MQTTnet.Benchmarks;
7 |
8 | [SimpleJob(RuntimeMoniker.Net60)]
9 | [RPlotExporter, RankColumn]
10 | [MemoryDiagnoser]
11 | public class RoundtripProcessingBenchmark : BaseBenchmark
12 | {
13 | [GlobalSetup]
14 | public void GlobalSetup()
15 | {
16 | TestEnvironment.EnableLogger = false;
17 | }
18 |
19 | [GlobalCleanup]
20 | public void GlobalCleanup()
21 | {
22 | }
23 |
24 | [Benchmark]
25 | public void Handle_100_000_Messages_In_Receiving_Client()
26 | {
27 | new Load_Tests().Handle_100_000_Messages_In_Receiving_Client().GetAwaiter().GetResult();
28 | }
29 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Benchmarks/ServerProcessingBenchmark.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using BenchmarkDotNet.Attributes;
6 | using BenchmarkDotNet.Jobs;
7 | using MQTTnet.Tests.Mockups;
8 | using MQTTnet.Tests.Server;
9 |
10 | namespace MQTTnet.Benchmarks;
11 |
12 | [SimpleJob(RuntimeMoniker.Net60)]
13 | [RPlotExporter, RankColumn]
14 | [MemoryDiagnoser]
15 | public class ServerProcessingBenchmark : BaseBenchmark
16 | {
17 | [GlobalSetup]
18 | public void GlobalSetup()
19 | {
20 | TestEnvironment.EnableLogger = false;
21 | }
22 |
23 | [GlobalCleanup]
24 | public void GlobalCleanup()
25 | {
26 | }
27 |
28 | [Benchmark]
29 | public void Handle_100_000_Messages_In_Server_MqttClient()
30 | {
31 | new Load_Tests().Handle_100_000_Messages_In_Server().GetAwaiter().GetResult();
32 | }
33 |
34 | //[Benchmark]
35 | public void Handle_100_000_Messages_In_Server_LowLevelMqttClient()
36 | {
37 | new Load_Tests().Handle_100_000_Messages_In_Low_Level_Client().GetAwaiter().GetResult();
38 | }
39 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Extensions.Rpc/DefaultMqttRpcClientTopicGenerationStrategy.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Extensions.Rpc;
8 |
9 | public sealed class DefaultMqttRpcClientTopicGenerationStrategy : IMqttRpcClientTopicGenerationStrategy
10 | {
11 | public MqttRpcTopicPair CreateRpcTopics(TopicGenerationContext context)
12 | {
13 | ArgumentNullException.ThrowIfNull(context);
14 |
15 | if (context.MethodName.Contains("/") || context.MethodName.Contains("+") || context.MethodName.Contains("#"))
16 | {
17 | throw new ArgumentException("The method name cannot contain /, + or #.");
18 | }
19 |
20 | var requestTopic = $"MQTTnet.RPC/{Guid.NewGuid():N}/{context.MethodName}";
21 | var responseTopic = requestTopic + "/response";
22 |
23 | return new MqttRpcTopicPair
24 | {
25 | RequestTopic = requestTopic,
26 | ResponseTopic = responseTopic
27 | };
28 | }
29 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Extensions.Rpc/IMqttRpcClient.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 | using MQTTnet.Protocol;
10 |
11 | namespace MQTTnet.Extensions.Rpc;
12 |
13 | public interface IMqttRpcClient : IDisposable
14 | {
15 | Task ExecuteAsync(TimeSpan timeout, string methodName, byte[] payload, MqttQualityOfServiceLevel qualityOfServiceLevel, IDictionary parameters = null);
16 |
17 | Task ExecuteAsync(string methodName, byte[] payload, MqttQualityOfServiceLevel qualityOfServiceLevel, IDictionary parameters = null, CancellationToken cancellationToken = default);
18 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Extensions.Rpc/IMqttRpcClientTopicGenerationStrategy.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Extensions.Rpc;
6 |
7 | public interface IMqttRpcClientTopicGenerationStrategy
8 | {
9 | MqttRpcTopicPair CreateRpcTopics(TopicGenerationContext context);
10 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
4 | True
6 | True
--------------------------------------------------------------------------------
/Source/MQTTnet.Extensions.Rpc/MqttFactoryExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Extensions.Rpc;
8 |
9 | public static class MqttFactoryExtensions
10 | {
11 | public static IMqttRpcClient CreateMqttRpcClient(this MqttClientFactory clientFactory, IMqttClient mqttClient)
12 | {
13 | return clientFactory.CreateMqttRpcClient(
14 | mqttClient,
15 | new MqttRpcClientOptions
16 | {
17 | TopicGenerationStrategy = new DefaultMqttRpcClientTopicGenerationStrategy()
18 | });
19 | }
20 |
21 | public static IMqttRpcClient CreateMqttRpcClient(this MqttClientFactory _, IMqttClient mqttClient, MqttRpcClientOptions rpcClientOptions)
22 | {
23 | ArgumentNullException.ThrowIfNull(mqttClient);
24 | ArgumentNullException.ThrowIfNull(rpcClientOptions);
25 |
26 | return new MqttRpcClient(mqttClient, rpcClientOptions);
27 | }
28 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Extensions.Rpc/MqttRpcClientExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using MQTTnet.Protocol;
10 |
11 | namespace MQTTnet.Extensions.Rpc;
12 |
13 | public static class MqttRpcClientExtensions
14 | {
15 | public static Task ExecuteAsync(this IMqttRpcClient client, TimeSpan timeout, string methodName, string payload, MqttQualityOfServiceLevel qualityOfServiceLevel, IDictionary parameters = null)
16 | {
17 | if (client == null) throw new ArgumentNullException(nameof(client));
18 |
19 | var buffer = Encoding.UTF8.GetBytes(payload ?? string.Empty);
20 |
21 | return client.ExecuteAsync(timeout, methodName, buffer, qualityOfServiceLevel, parameters);
22 | }
23 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Extensions.Rpc/MqttRpcClientOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Extensions.Rpc;
6 |
7 | public sealed class MqttRpcClientOptions
8 | {
9 | public IMqttRpcClientTopicGenerationStrategy TopicGenerationStrategy { get; set; } = new DefaultMqttRpcClientTopicGenerationStrategy();
10 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Extensions.Rpc/MqttRpcClientOptionsBuilder.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Extensions.Rpc;
8 |
9 | public sealed class MqttRpcClientOptionsBuilder
10 | {
11 | IMqttRpcClientTopicGenerationStrategy _topicGenerationStrategy = new DefaultMqttRpcClientTopicGenerationStrategy();
12 |
13 | public MqttRpcClientOptions Build()
14 | {
15 | return new MqttRpcClientOptions
16 | {
17 | TopicGenerationStrategy = _topicGenerationStrategy
18 | };
19 | }
20 |
21 | public MqttRpcClientOptionsBuilder WithTopicGenerationStrategy(IMqttRpcClientTopicGenerationStrategy value)
22 | {
23 | _topicGenerationStrategy = value ?? throw new ArgumentNullException(nameof(value));
24 |
25 | return this;
26 | }
27 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Extensions.Rpc/MqttRpcTopicPair.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Extensions.Rpc;
6 |
7 | public sealed class MqttRpcTopicPair
8 | {
9 | public string RequestTopic { get; set; }
10 |
11 | public string ResponseTopic { get; set; }
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Extensions.Rpc/SampleCCode.c:
--------------------------------------------------------------------------------
1 | // If using the MQTT client PubSubClient it must be ensured that the request topic for each method is subscribed like the following.
2 | _mqttClient.subscribe("MQTTnet.RPC/+/ping");
3 | _mqttClient.subscribe("MQTTnet.RPC/+/do_something");
4 |
5 | // It is not allowed to change the structure of the topic. Otherwise RPC will not work. So method names can be separated using
6 | // an _ or . but no +, # or /. If it is required to distinguish between devices own rules can be defined like the following.
7 | _mqttClient.subscribe("MQTTnet.RPC/+/deviceA.ping");
8 | _mqttClient.subscribe("MQTTnet.RPC/+/deviceB.ping");
9 | _mqttClient.subscribe("MQTTnet.RPC/+/deviceC.getTemperature");
10 |
11 | // Within the callback of the MQTT client the topic must be checked if it belongs to MQTTnet RPC. The following code shows one
12 | // possible way of doing this.
13 | void mqtt_Callback(char *topic, byte *payload, unsigned int payloadLength)
14 | {
15 | String topicString = String(topic);
16 |
17 | if (topicString.startsWith("MQTTnet.RPC/")) {
18 | String responseTopic = topicString + String("/response");
19 |
20 | if (topicString.endsWith("/deviceA.ping")) {
21 | mqtt_publish(responseTopic, "pong", false);
22 | return;
23 | }
24 | }
25 | }
26 |
27 | // Important notes:
28 | // ! Do not send response message with the _retain_ flag set to true.
29 | // ! All required data for a RPC call and the result must be placed into the payload.
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Disconnecting/MqttServerClientDisconnectOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server;
9 |
10 | public sealed class MqttServerClientDisconnectOptions
11 | {
12 | public MqttDisconnectReasonCode ReasonCode { get; set; } = MqttDisconnectReasonCode.NormalDisconnection;
13 |
14 | ///
15 | /// The reason string is sent to every client via a DISCONNECT packet.
16 | /// MQTT 5.0.0+ feature.
17 | ///
18 | public string ReasonString { get; set; }
19 |
20 | ///
21 | /// The server reference is sent to every client via a DISCONNECT packet.
22 | /// MQTT 5.0.0+ feature.
23 | ///
24 | public string ServerReference { get; set; }
25 |
26 | ///
27 | /// These user properties are sent to every client via a DISCONNECT packet.
28 | /// MQTT 5.0.0+ feature.
29 | ///
30 | public List UserProperties { get; set; }
31 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/EnhancedAuthentication/ExchangeEnhancedAuthenticationOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 |
7 | namespace MQTTnet.Server.EnhancedAuthentication;
8 |
9 | public sealed class ExchangeEnhancedAuthenticationOptions
10 | {
11 | public byte[] AuthenticationData { get; set; }
12 |
13 | public string ReasonString { get; set; }
14 |
15 | public List UserProperties { get; set; }
16 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/EnhancedAuthentication/ExchangeEnhancedAuthenticationResult.cs:
--------------------------------------------------------------------------------
1 | using MQTTnet.Packets;
2 |
3 | namespace MQTTnet.Server.EnhancedAuthentication;
4 |
5 | public sealed class ExchangeEnhancedAuthenticationResult
6 | {
7 | public string ReasonString { get; set; }
8 |
9 | public List UserProperties { get; set; }
10 |
11 | public byte[] AuthenticationData { get; set; }
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/EnhancedAuthentication/ExchangeEnhancedAuthenticationResultFactory.cs:
--------------------------------------------------------------------------------
1 | using MQTTnet.Packets;
2 |
3 | namespace MQTTnet.Server.EnhancedAuthentication;
4 |
5 | public static class ExchangeEnhancedAuthenticationResultFactory
6 | {
7 | public static ExchangeEnhancedAuthenticationResult Create(MqttAuthPacket authPacket)
8 | {
9 | ArgumentNullException.ThrowIfNull(authPacket);
10 |
11 | return new ExchangeEnhancedAuthenticationResult
12 | {
13 | AuthenticationData = authPacket.AuthenticationData,
14 |
15 | ReasonString = authPacket.ReasonString,
16 | UserProperties = authPacket.UserProperties
17 | };
18 | }
19 |
20 | public static ExchangeEnhancedAuthenticationResult Create(MqttDisconnectPacket disconnectPacket)
21 | {
22 | ArgumentNullException.ThrowIfNull(disconnectPacket);
23 |
24 | return new ExchangeEnhancedAuthenticationResult
25 | {
26 | AuthenticationData = null,
27 | ReasonString = disconnectPacket.ReasonString,
28 | UserProperties = disconnectPacket.UserProperties
29 |
30 | // SessionExpiryInterval makes no sense because the connection is not yet made!
31 | // ServerReferences makes no sense when the client initiated a DISCONNECT!
32 | };
33 | }
34 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Events/ApplicationMessageEnqueuedEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public sealed class ApplicationMessageEnqueuedEventArgs : EventArgs
8 | {
9 | public ApplicationMessageEnqueuedEventArgs(string senderClientId, string receiverClientId, MqttApplicationMessage applicationMessage, bool isDropped)
10 | {
11 | SenderClientId = senderClientId ?? throw new ArgumentNullException( nameof(senderClientId));
12 | ReceiverClientId = receiverClientId ?? throw new ArgumentNullException(nameof(receiverClientId));
13 | ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
14 | IsDropped = isDropped;
15 | }
16 |
17 | public string SenderClientId { get; }
18 |
19 | public string ReceiverClientId { get; }
20 |
21 | public bool IsDropped { get; }
22 |
23 | public MqttApplicationMessage ApplicationMessage { get; }
24 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Events/ApplicationMessageNotConsumedEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public sealed class ApplicationMessageNotConsumedEventArgs : EventArgs
8 | {
9 | public ApplicationMessageNotConsumedEventArgs(MqttApplicationMessage applicationMessage, string senderId)
10 | {
11 | ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
12 | SenderId = senderId;
13 | }
14 |
15 | ///
16 | /// Gets the application message which was not consumed by any client.
17 | ///
18 | public MqttApplicationMessage ApplicationMessage { get; }
19 |
20 | ///
21 | /// Gets the ID of the client which has sent the affected application message.
22 | ///
23 | public string SenderId { get; }
24 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Events/ClientUnsubscribedTopicEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections;
6 |
7 | namespace MQTTnet.Server;
8 |
9 | public sealed class ClientUnsubscribedTopicEventArgs : EventArgs
10 | {
11 | public ClientUnsubscribedTopicEventArgs(string clientId, string userName, string topicFilter, IDictionary sessionItems)
12 | {
13 | ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
14 | UserName = userName;
15 | TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
16 | SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
17 | }
18 |
19 | ///
20 | /// Gets the client identifier.
21 | /// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
22 | ///
23 | public string ClientId { get; }
24 |
25 | ///
26 | /// Gets the user name of the client.
27 | ///
28 | public string UserName { get; }
29 |
30 | ///
31 | /// Gets or sets a key/value collection that can be used to share data within the scope of this session.
32 | ///
33 | public IDictionary SessionItems { get; }
34 |
35 | ///
36 | /// Gets or sets the topic filter.
37 | /// The topic filter can contain topics and wildcards.
38 | ///
39 | public string TopicFilter { get; }
40 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Events/InterceptingClientApplicationMessageEnqueueEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public sealed class InterceptingClientApplicationMessageEnqueueEventArgs : EventArgs
8 | {
9 | public InterceptingClientApplicationMessageEnqueueEventArgs(string senderClientId, string receiverClientId, MqttApplicationMessage applicationMessage)
10 | {
11 | SenderClientId = senderClientId ?? throw new ArgumentNullException(nameof(senderClientId));
12 | ReceiverClientId = receiverClientId ?? throw new ArgumentNullException(nameof(receiverClientId));
13 | ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
14 | }
15 |
16 | ///
17 | /// Gets or sets whether the enqueue of the application message should be performed or not.
18 | /// If set to _False_ the client will not receive the application message.
19 | ///
20 | public bool AcceptEnqueue { get; set; } = true;
21 |
22 | public MqttApplicationMessage ApplicationMessage { get; }
23 |
24 | ///
25 | /// Indicates if the connection with the sender should be closed.
26 | ///
27 | public bool CloseSenderConnection { get; set; }
28 |
29 | public string ReceiverClientId { get; }
30 |
31 | public string SenderClientId { get; }
32 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Events/LoadingRetainedMessagesEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public sealed class LoadingRetainedMessagesEventArgs : EventArgs
8 | {
9 | public List LoadedRetainedMessages { get; set; } = new List();
10 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Events/QueueMessageOverwrittenEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 |
7 | namespace MQTTnet.Server;
8 |
9 | public sealed class QueueMessageOverwrittenEventArgs : EventArgs
10 | {
11 | public QueueMessageOverwrittenEventArgs(string receiverClientId, MqttPacket packet)
12 | {
13 | ReceiverClientId = receiverClientId ?? throw new ArgumentNullException(nameof(receiverClientId));
14 | Packet = packet ?? throw new ArgumentNullException(nameof(packet));
15 | }
16 |
17 | public MqttPacket Packet { get; }
18 |
19 | public string ReceiverClientId { get; }
20 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Events/RetainedMessageChangedEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public sealed class RetainedMessageChangedEventArgs : EventArgs
8 | {
9 | public RetainedMessageChangedEventArgs(string clientId, MqttApplicationMessage changedRetainedMessage, List storedRetainedMessages)
10 | {
11 | ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
12 | ChangedRetainedMessage = changedRetainedMessage ?? throw new ArgumentNullException(nameof(changedRetainedMessage));
13 | StoredRetainedMessages = storedRetainedMessages ?? throw new ArgumentNullException(nameof(storedRetainedMessages));
14 | }
15 |
16 | public MqttApplicationMessage ChangedRetainedMessage { get; }
17 |
18 | public string ClientId { get; }
19 |
20 | public List StoredRetainedMessages { get; }
21 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Events/SessionDeletedEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections;
6 |
7 | namespace MQTTnet.Server;
8 |
9 | public sealed class SessionDeletedEventArgs : EventArgs
10 | {
11 | public SessionDeletedEventArgs(string id, string userName, IDictionary sessionItems)
12 | {
13 | Id = id ?? throw new ArgumentNullException(nameof(id));
14 | UserName = userName;
15 | SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
16 | }
17 |
18 | ///
19 | /// Gets the ID of the session.
20 | ///
21 | public string Id { get; }
22 |
23 | ///
24 | /// Gets the user name of the session.
25 | ///
26 | public string UserName { get; }
27 |
28 | ///
29 | /// Gets or sets a key/value collection that can be used to share data within the scope of this session.
30 | ///
31 | public IDictionary SessionItems { get; }
32 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Exceptions/MqttPendingMessagesOverflowException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server.Exceptions;
6 |
7 | public class MqttPendingMessagesOverflowException : Exception
8 | {
9 | public MqttPendingMessagesOverflowException(string sessionId, MqttPendingMessagesOverflowStrategy overflowStrategy) : base(
10 | $"Send buffer max pending messages overflow occurred for session '{sessionId}'. Strategy: {overflowStrategy}.")
11 | {
12 | SessionId = sessionId;
13 | OverflowStrategy = overflowStrategy;
14 | }
15 |
16 | public MqttPendingMessagesOverflowStrategy OverflowStrategy { get; }
17 |
18 | public string SessionId { get; }
19 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/IMqttServerAdapter.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Adapter;
6 | using MQTTnet.Diagnostics.Logger;
7 |
8 | namespace MQTTnet.Server;
9 |
10 | public interface IMqttServerAdapter : IDisposable
11 | {
12 | Func ClientHandler { get; set; }
13 |
14 | Task StartAsync(MqttServerOptions options, IMqttNetLogger logger);
15 |
16 | Task StopAsync();
17 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/InjectedMqttApplicationMessage.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections;
6 |
7 | namespace MQTTnet.Server;
8 |
9 | public sealed class InjectedMqttApplicationMessage
10 | {
11 | public InjectedMqttApplicationMessage(MqttApplicationMessage applicationMessage)
12 | {
13 | ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
14 | }
15 |
16 | public MqttApplicationMessage ApplicationMessage { get; }
17 |
18 | ///
19 | /// Gets or sets the session items which should be used for all event handlers which are involved in message
20 | /// processing.
21 | /// If _null_ is specified the singleton session items from the server are used instead.
22 | ///
23 | public IDictionary CustomSessionItems { get; set; }
24 |
25 | public string SenderClientId { get; set; } = string.Empty;
26 |
27 | public string SenderUserName { get; set; }
28 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/CheckSubscriptionsResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Protocol;
6 |
7 | namespace MQTTnet.Server.Internal;
8 |
9 | public sealed class CheckSubscriptionsResult
10 | {
11 | public static CheckSubscriptionsResult NotSubscribed { get; } = new CheckSubscriptionsResult();
12 |
13 | public bool IsSubscribed { get; set; }
14 |
15 | public bool RetainAsPublished { get; set; }
16 |
17 | public List SubscriptionIdentifiers { get; set; }
18 |
19 | public MqttQualityOfServiceLevel QualityOfServiceLevel { get; set; }
20 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/DispatchApplicationMessageResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 |
7 | namespace MQTTnet.Server.Internal;
8 |
9 | public sealed class DispatchApplicationMessageResult
10 | {
11 | public DispatchApplicationMessageResult(int reasonCode, bool closeConnection, string reasonString, List userProperties)
12 | {
13 | ReasonCode = reasonCode;
14 | CloseConnection = closeConnection;
15 | ReasonString = reasonString;
16 | UserProperties = userProperties;
17 | }
18 |
19 | public bool CloseConnection { get; }
20 |
21 | public int ReasonCode { get; }
22 |
23 | public string ReasonString { get; }
24 |
25 | public List UserProperties { get; }
26 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/EnqueueDataPacketResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server.Internal;
6 |
7 | public enum EnqueueDataPacketResult
8 | {
9 | Enqueued,
10 | Dropped
11 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/Formatter/MqttDisconnectPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server.Internal.Formatter;
9 |
10 | public static class MqttDisconnectPacketFactory
11 | {
12 | static readonly MqttDisconnectPacket DefaultNormalDisconnection = new()
13 | {
14 | ReasonCode = MqttDisconnectReasonCode.NormalDisconnection,
15 | UserProperties = null,
16 | ReasonString = null,
17 | ServerReference = null,
18 | SessionExpiryInterval = 0
19 | };
20 |
21 | public static MqttDisconnectPacket Create(MqttServerClientDisconnectOptions clientDisconnectOptions)
22 | {
23 | if (clientDisconnectOptions == null)
24 | {
25 | return DefaultNormalDisconnection;
26 | }
27 |
28 | return new MqttDisconnectPacket
29 | {
30 | ReasonCode = clientDisconnectOptions.ReasonCode,
31 | UserProperties = clientDisconnectOptions.UserProperties,
32 | ReasonString = clientDisconnectOptions.ReasonString,
33 | ServerReference = clientDisconnectOptions.ServerReference,
34 | SessionExpiryInterval = 0 // TODO: Not yet supported!
35 | };
36 | }
37 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/Formatter/MqttPubAckPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server.Internal.Formatter;
9 |
10 | public static class MqttPubAckPacketFactory
11 | {
12 | public static MqttPubAckPacket Create(MqttPublishPacket publishPacket, DispatchApplicationMessageResult dispatchApplicationMessageResult)
13 | {
14 | ArgumentNullException.ThrowIfNull(publishPacket);
15 | ArgumentNullException.ThrowIfNull(dispatchApplicationMessageResult);
16 |
17 | var pubAckPacket = new MqttPubAckPacket
18 | {
19 | PacketIdentifier = publishPacket.PacketIdentifier,
20 | ReasonCode = (MqttPubAckReasonCode)dispatchApplicationMessageResult.ReasonCode,
21 | ReasonString = dispatchApplicationMessageResult.ReasonString,
22 | UserProperties = dispatchApplicationMessageResult.UserProperties
23 | };
24 |
25 | return pubAckPacket;
26 | }
27 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/Formatter/MqttPubCompPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server.Internal.Formatter;
9 |
10 | public static class MqttPubCompPacketFactory
11 | {
12 | public static MqttPubCompPacket Create(MqttPubRelPacket pubRelPacket, MqttApplicationMessageReceivedReasonCode reasonCode)
13 | {
14 | ArgumentNullException.ThrowIfNull(pubRelPacket);
15 |
16 | return new MqttPubCompPacket
17 | {
18 | PacketIdentifier = pubRelPacket.PacketIdentifier,
19 | ReasonCode = (MqttPubCompReasonCode)(int)reasonCode
20 | };
21 | }
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/Formatter/MqttPubRecPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server.Internal.Formatter;
9 |
10 | public static class MqttPubRecPacketFactory
11 | {
12 | public static MqttPacket Create(MqttPublishPacket publishPacket, DispatchApplicationMessageResult dispatchApplicationMessageResult)
13 | {
14 | ArgumentNullException.ThrowIfNull(publishPacket);
15 |
16 | var pubRecPacket = new MqttPubRecPacket
17 | {
18 | PacketIdentifier = publishPacket.PacketIdentifier,
19 | ReasonCode = (MqttPubRecReasonCode)dispatchApplicationMessageResult.ReasonCode,
20 | ReasonString = dispatchApplicationMessageResult.ReasonString,
21 | UserProperties = dispatchApplicationMessageResult.UserProperties
22 | };
23 |
24 | return pubRecPacket;
25 | }
26 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/Formatter/MqttPubRelPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server.Internal.Formatter;
9 |
10 | public static class MqttPubRelPacketFactory
11 | {
12 | public static MqttPubRelPacket Create(MqttPubRecPacket pubRecPacket, MqttApplicationMessageReceivedReasonCode reasonCode)
13 | {
14 | ArgumentNullException.ThrowIfNull(pubRecPacket);
15 |
16 | return new MqttPubRelPacket
17 | {
18 | PacketIdentifier = pubRecPacket.PacketIdentifier,
19 | ReasonCode = (MqttPubRelReasonCode)(int)reasonCode
20 | };
21 | }
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/Formatter/MqttSubAckPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 |
7 | namespace MQTTnet.Server.Internal.Formatter;
8 |
9 | public static class MqttSubAckPacketFactory
10 | {
11 | public static MqttSubAckPacket Create(MqttSubscribePacket subscribePacket, SubscribeResult subscribeResult)
12 | {
13 | ArgumentNullException.ThrowIfNull(subscribePacket);
14 | ArgumentNullException.ThrowIfNull(subscribeResult);
15 |
16 | var subAckPacket = new MqttSubAckPacket
17 | {
18 | PacketIdentifier = subscribePacket.PacketIdentifier,
19 | ReasonCodes = subscribeResult.ReasonCodes,
20 | ReasonString = subscribeResult.ReasonString,
21 | UserProperties = subscribeResult.UserProperties
22 | };
23 |
24 | return subAckPacket;
25 | }
26 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/Formatter/MqttUnsubAckPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 |
7 | namespace MQTTnet.Server.Internal.Formatter;
8 |
9 | public static class MqttUnsubAckPacketFactory
10 | {
11 | public static MqttUnsubAckPacket Create(MqttUnsubscribePacket unsubscribePacket, UnsubscribeResult unsubscribeResult)
12 | {
13 | ArgumentNullException.ThrowIfNull(unsubscribePacket);
14 | ArgumentNullException.ThrowIfNull(unsubscribeResult);
15 |
16 | var unsubAckPacket = new MqttUnsubAckPacket
17 | {
18 | PacketIdentifier = unsubscribePacket.PacketIdentifier
19 | };
20 |
21 | // MQTTv5.0.0 only.
22 | unsubAckPacket.ReasonCodes = unsubscribeResult.ReasonCodes;
23 |
24 | return unsubAckPacket;
25 | }
26 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/ISubscriptionChangedNotification.cs:
--------------------------------------------------------------------------------
1 | namespace MQTTnet.Server.Internal;
2 |
3 | public interface ISubscriptionChangedNotification
4 | {
5 | void OnSubscriptionsAdded(MqttSession clientSession, List subscriptionsTopics);
6 |
7 | void OnSubscriptionsRemoved(MqttSession clientSession, List subscriptionTopics);
8 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/MqttSubscription.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Protocol;
6 |
7 | namespace MQTTnet.Server.Internal;
8 |
9 | public sealed class MqttSubscription
10 | {
11 | public MqttSubscription(
12 | string topic,
13 | bool noLocal,
14 | MqttRetainHandling retainHandling,
15 | bool retainAsPublished,
16 | MqttQualityOfServiceLevel qualityOfServiceLevel,
17 | uint identifier)
18 | {
19 | Topic = topic;
20 | NoLocal = noLocal;
21 | RetainHandling = retainHandling;
22 | RetainAsPublished = retainAsPublished;
23 | GrantedQualityOfServiceLevel = qualityOfServiceLevel;
24 | Identifier = identifier;
25 |
26 | MqttTopicHash.Calculate(Topic, out var hash, out var hashMask, out var hasWildcard);
27 | TopicHash = hash;
28 | TopicHashMask = hashMask;
29 | TopicHasWildcard = hasWildcard;
30 | }
31 |
32 | public MqttQualityOfServiceLevel GrantedQualityOfServiceLevel { get; }
33 |
34 | public uint Identifier { get; }
35 |
36 | public bool NoLocal { get; }
37 |
38 | public bool RetainAsPublished { get; }
39 |
40 | public MqttRetainHandling RetainHandling { get; }
41 |
42 | public string Topic { get; }
43 |
44 | public ulong TopicHash { get; }
45 |
46 | public ulong TopicHashMask { get; }
47 |
48 | public bool TopicHasWildcard { get; }
49 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/SubscribeResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server.Internal;
9 |
10 | public sealed class SubscribeResult
11 | {
12 | public SubscribeResult(int topicsCount)
13 | {
14 | ReasonCodes = new List(topicsCount);
15 | }
16 |
17 | public bool CloseConnection { get; set; }
18 |
19 | public List ReasonCodes { get; set; }
20 |
21 | public string ReasonString { get; set; }
22 |
23 | public List RetainedMessages { get; set; }
24 |
25 | public List UserProperties { get; set; }
26 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/TopicHashMaskSubscriptions.cs:
--------------------------------------------------------------------------------
1 | namespace MQTTnet.Server.Internal;
2 |
3 | ///
4 | /// Helper class that stores subscriptions by their topic hash mask.
5 | ///
6 | public sealed class TopicHashMaskSubscriptions
7 | {
8 | public Dictionary> SubscriptionsByHashMask { get; } = new Dictionary>();
9 |
10 | public void AddSubscription(MqttSubscription subscription)
11 | {
12 | if (!SubscriptionsByHashMask.TryGetValue(subscription.TopicHashMask, out var subscriptions))
13 | {
14 | subscriptions = new HashSet();
15 | SubscriptionsByHashMask.Add(subscription.TopicHashMask, subscriptions);
16 | }
17 | subscriptions.Add(subscription);
18 | }
19 |
20 | public void RemoveSubscription(MqttSubscription subscription)
21 | {
22 | if (SubscriptionsByHashMask.TryGetValue(subscription.TopicHashMask, out var subscriptions))
23 | {
24 | subscriptions.Remove(subscription);
25 | if (subscriptions.Count == 0)
26 | {
27 | SubscriptionsByHashMask.Remove(subscription.TopicHashMask);
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Internal/UnsubscribeResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server.Internal;
9 |
10 | public sealed class UnsubscribeResult
11 | {
12 | public List ReasonCodes { get; } = new List(128);
13 |
14 | public bool CloseConnection { get; set; }
15 |
16 | public List UserProperties { get; set; }
17 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/MQTTnet.Server.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
4 | True
6 | True
8 | True
10 | True
12 | True
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/MqttClientDisconnectType.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public enum MqttClientDisconnectType
8 | {
9 | Clean,
10 | NotClean,
11 | Takeover
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/MqttRetainedMessageMatch.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Protocol;
6 |
7 | namespace MQTTnet.Server;
8 |
9 | public sealed class MqttRetainedMessageMatch
10 | {
11 | public MqttRetainedMessageMatch(MqttApplicationMessage applicationMessage, MqttQualityOfServiceLevel subscriptionQualityOfServiceLevel)
12 | {
13 | ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
14 | SubscriptionQualityOfServiceLevel = subscriptionQualityOfServiceLevel;
15 | }
16 |
17 | public MqttApplicationMessage ApplicationMessage { get; }
18 |
19 | public MqttQualityOfServiceLevel SubscriptionQualityOfServiceLevel { get; set; }
20 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Options/IMqttServerCertificateCredentials.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public interface IMqttServerCertificateCredentials
8 | {
9 | string Password { get; }
10 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Options/MqttPendingMessagesOverflowStrategy.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public enum MqttPendingMessagesOverflowStrategy
8 | {
9 | DropOldestQueuedMessage,
10 |
11 | DropNewMessage
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Options/MqttServerCertificateCredentials.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public class MqttServerCertificateCredentials : IMqttServerCertificateCredentials
8 | {
9 | public string Password { get; set; }
10 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Options/MqttServerKeepAliveOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public sealed class MqttServerKeepAliveOptions
8 | {
9 | ///
10 | /// When this mode is enabled the MQTT server will not close a connection when the
11 | /// client is currently sending a (large) payload. This may lead to "dead" connections
12 | /// When this mode is disabled the MQTT server will disconnect a client when the keep
13 | /// alive timeout is reached even if the client is currently sending a (large) payload.
14 | ///
15 | public bool DisconnectClientWhenReadingPayload { get; set; }
16 |
17 | public TimeSpan MonitorInterval { get; set; } = TimeSpan.FromMilliseconds(500);
18 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Options/MqttServerTcpEndpointOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public class MqttServerTcpEndpointOptions : MqttServerTcpEndpointBaseOptions
8 | {
9 | public MqttServerTcpEndpointOptions()
10 | {
11 | Port = 1883;
12 | }
13 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Options/MqttServerTlsTcpEndpointOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Security.Authentication;
6 | using MQTTnet.Certificates;
7 |
8 | namespace MQTTnet.Server;
9 |
10 | public sealed class MqttServerTlsTcpEndpointOptions : MqttServerTcpEndpointBaseOptions
11 | {
12 | public MqttServerTlsTcpEndpointOptions()
13 | {
14 | Port = 8883;
15 | }
16 |
17 | public System.Net.Security.RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; }
18 |
19 | public ICertificateProvider CertificateProvider { get; set; }
20 |
21 | public bool ClientCertificateRequired { get; set; }
22 |
23 | public bool CheckCertificateRevocation { get; set; }
24 |
25 | ///
26 | /// The default value is SslProtocols.None, which allows the operating system to choose the best protocol to use, and to block protocols that are not secure.
27 | ///
28 | /// SslProtocols
29 | public SslProtocols SslProtocol { get; set; } = SslProtocols.None;
30 |
31 | public System.Net.Security.CipherSuitesPolicy CipherSuitesPolicy { get; set; }
32 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/PublishResponse.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server;
9 |
10 | public sealed class PublishResponse
11 | {
12 | public MqttPubAckReasonCode ReasonCode { get; set; } = MqttPubAckReasonCode.Success;
13 |
14 | public string ReasonString { get; set; }
15 |
16 | public List UserProperties { get; set; }
17 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Status/MqttClientStatusExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Protocol;
6 |
7 | namespace MQTTnet.Server;
8 |
9 | public static class MqttClientStatusExtensions
10 | {
11 | static readonly MqttServerClientDisconnectOptions DefaultDisconnectOptions = new()
12 | {
13 | ReasonCode = MqttDisconnectReasonCode.NormalDisconnection,
14 | ReasonString = null,
15 | UserProperties = null,
16 | ServerReference = null
17 | };
18 |
19 | public static Task DisconnectAsync(this MqttClientStatus clientStatus)
20 | {
21 | ArgumentNullException.ThrowIfNull(clientStatus);
22 |
23 | return clientStatus.DisconnectAsync(DefaultDisconnectOptions);
24 | }
25 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Stopping/MqttServerStopOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Protocol;
6 |
7 | namespace MQTTnet.Server;
8 |
9 | public sealed class MqttServerStopOptions
10 | {
11 | ///
12 | /// These disconnect options are sent to every connected client via a DISCONNECT packet.
13 | /// MQTT 5.0.0+ feature.
14 | ///
15 | public MqttServerClientDisconnectOptions DefaultClientDisconnectOptions { get; set; } = new MqttServerClientDisconnectOptions
16 | {
17 | ReasonCode = MqttDisconnectReasonCode.ServerShuttingDown,
18 | UserProperties = null,
19 | ReasonString = null,
20 | ServerReference = null
21 | };
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/Stopping/MqttServerStopOptionsBuilder.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Server;
6 |
7 | public sealed class MqttServerStopOptionsBuilder
8 | {
9 | readonly MqttServerStopOptions _options = new();
10 |
11 | public MqttServerStopOptionsBuilder WithDefaultClientDisconnectOptions(MqttServerClientDisconnectOptions value)
12 | {
13 | _options.DefaultClientDisconnectOptions = value;
14 | return this;
15 | }
16 |
17 | public MqttServerStopOptionsBuilder WithDefaultClientDisconnectOptions(Action builder)
18 | {
19 | ArgumentNullException.ThrowIfNull(builder);
20 |
21 | var optionsBuilder = new MqttServerClientDisconnectOptionsBuilder();
22 | builder(optionsBuilder);
23 |
24 | _options.DefaultClientDisconnectOptions = optionsBuilder.Build();
25 | return this;
26 | }
27 |
28 | public MqttServerStopOptions Build()
29 | {
30 | return _options;
31 | }
32 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/SubscribeResponse.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server;
9 |
10 | public sealed class SubscribeResponse
11 | {
12 | ///
13 | /// Gets or sets the reason code which is sent to the client.
14 | /// The subscription is skipped when the value is not GrantedQoS_.
15 | /// MQTTv5 only.
16 | ///
17 | public MqttSubscribeReasonCode ReasonCode { get; set; }
18 |
19 | public string ReasonString { get; set; }
20 |
21 | public List UserProperties { get; } = [];
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Server/UnsubscribeResponse.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Server;
9 |
10 | public sealed class UnsubscribeResponse
11 | {
12 | ///
13 | /// Gets or sets the reason code which is sent to the client.
14 | /// MQTTv5 only.
15 | ///
16 | public MqttUnsubscribeReasonCode ReasonCode { get; set; }
17 |
18 | public string ReasonString { get; set; }
19 |
20 | public List UserProperties { get; } = [];
21 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.TestApp/AsyncLockTest.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 | using MQTTnet.Exceptions;
9 |
10 | namespace MQTTnet.TestApp;
11 |
12 | public sealed class AsyncLockTest
13 | {
14 | public async Task Run()
15 | {
16 | try
17 | {
18 | var semaphore = new SemaphoreSlim(1, 1);
19 |
20 | await semaphore.WaitAsync();
21 | try
22 | {
23 | // Wait for data from socket etc...
24 | // Then get an exception.
25 | semaphore.Dispose();
26 | throw new MqttCommunicationException("Connection closed");
27 | }
28 | finally
29 | {
30 | semaphore.Release();
31 | }
32 | }
33 | catch (Exception exception)
34 | {
35 | Console.WriteLine(exception.ToString());
36 | }
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | // var asyncLock = new AsyncLock();
50 | //
51 | // using var cancellationToken = new CancellationTokenSource();
52 | // for (var i = 0; i < 100000; i++)
53 | // {
54 | // using (await asyncLock.EnterAsync(cancellationToken.Token).ConfigureAwait(false))
55 | // {
56 | // }
57 | // }
58 | }
59 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.TestApp/MQTTnet.TestApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | Full
6 | net8.0
7 | false
8 | false
9 | false
10 | true
11 | 1591;NETSDK1138;NU1803;NU1901;NU1902
12 | true
13 | all
14 | true
15 | low
16 | latest-Recommended
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Source/MQTTnet.TestApp/ServerAndClientTest.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using MQTTnet.Diagnostics.Logger;
8 | using MQTTnet.Server;
9 |
10 | namespace MQTTnet.TestApp;
11 |
12 | public static class ServerAndClientTest
13 | {
14 | public static async Task RunAsync()
15 | {
16 | var logger = new MqttNetEventLogger();
17 | MqttNetConsoleLogger.ForwardToConsole(logger);
18 |
19 | var mqttServerFactory = new MqttServerFactory();
20 | var mqttClientFactory = new MqttClientFactory(logger);
21 | var server = mqttServerFactory.CreateMqttServer( new MqttServerOptionsBuilder().Build());
22 | var client = mqttClientFactory.CreateMqttClient();
23 |
24 | await server.StartAsync();
25 |
26 | var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("localhost").Build();
27 | await client.ConnectAsync(clientOptions);
28 |
29 | await Task.Delay(Timeout.Infinite);
30 | }
31 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/ASP/Mockups/ConnectionHandlerMockup.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Threading.Tasks;
7 | using Microsoft.AspNetCore.Connections;
8 | using MQTTnet.Adapter;
9 | using MQTTnet.AspNetCore;
10 | using MQTTnet.Diagnostics.Logger;
11 | using MQTTnet.Formatter;
12 | using MQTTnet.Server;
13 |
14 | namespace MQTTnet.Tests.ASP.Mockups;
15 |
16 | public sealed class ConnectionHandlerMockup : IMqttServerAdapter
17 | {
18 | public Func ClientHandler { get; set; }
19 | public TaskCompletionSource Context { get; } = new();
20 |
21 | public void Dispose()
22 | {
23 | }
24 |
25 | public async Task OnConnectedAsync(ConnectionContext connection)
26 | {
27 | try
28 | {
29 | var formatter = new MqttPacketFormatterAdapter(new MqttBufferWriter(4096, 65535));
30 | var context = new MqttConnectionContext(formatter, connection);
31 | Context.TrySetResult(context);
32 |
33 | await ClientHandler(context);
34 | }
35 | catch (Exception ex)
36 | {
37 | Context.TrySetException(ex);
38 | }
39 | }
40 |
41 | public Task StartAsync(MqttServerOptions options, IMqttNetLogger logger)
42 | {
43 | return Task.CompletedTask;
44 | }
45 |
46 | public Task StopAsync()
47 | {
48 | return Task.CompletedTask;
49 | }
50 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/ASP/Mockups/DuplexPipeMockup.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.IO.Pipelines;
6 |
7 | namespace MQTTnet.Tests.ASP.Mockups;
8 |
9 | public sealed class DuplexPipeMockup : IDuplexPipe
10 | {
11 | public DuplexPipeMockup()
12 | {
13 | var pool = new LimitedMemoryPool();
14 | var pipeOptions = new PipeOptions(pool);
15 | Receive = new Pipe(pipeOptions);
16 | Send = new Pipe(pipeOptions);
17 | }
18 |
19 | PipeReader IDuplexPipe.Input => Receive.Reader;
20 |
21 | PipeWriter IDuplexPipe.Output => Send.Writer;
22 |
23 | public Pipe Receive { get; }
24 |
25 | public Pipe Send { get; }
26 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/ASP/Mockups/LimitedMemoryPool.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Buffers;
6 |
7 | namespace MQTTnet.Tests.ASP.Mockups;
8 |
9 | public sealed class LimitedMemoryPool : MemoryPool
10 | {
11 | protected override void Dispose(bool disposing)
12 | {
13 | }
14 |
15 | public override IMemoryOwner Rent(int minBufferSize = -1)
16 | {
17 | return new MemoryOwner(minBufferSize);
18 | }
19 |
20 | public override int MaxBufferSize { get; } = 1;
21 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/ASP/Mockups/MemoryOwner.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Buffers;
7 |
8 | namespace MQTTnet.Tests.ASP.Mockups;
9 |
10 | public sealed class MemoryOwner : IMemoryOwner
11 | {
12 | readonly byte[] _raw;
13 |
14 | public MemoryOwner(int size)
15 | {
16 | if (size <= 0)
17 | {
18 | size = 1024;
19 | }
20 |
21 | if (size > 4096)
22 | {
23 | size = 4096;
24 | }
25 |
26 | _raw = ArrayPool.Shared.Rent(size);
27 | Memory = _raw;
28 | }
29 |
30 | public Memory Memory { get; }
31 |
32 | public void Dispose()
33 | {
34 | ArrayPool.Shared.Return(_raw);
35 | }
36 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/BaseTestClass.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Threading.Tasks;
7 | using Microsoft.VisualStudio.TestTools.UnitTesting;
8 | using MQTTnet.Formatter;
9 | using MQTTnet.Tests.Mockups;
10 |
11 | namespace MQTTnet.Tests;
12 |
13 | public abstract class BaseTestClass
14 | {
15 | public TestContext TestContext { get; set; }
16 |
17 | protected TestEnvironment CreateTestEnvironment(
18 | MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311, bool trackUnobservedTaskException = true)
19 | {
20 | return new TestEnvironment(TestContext, protocolVersion, trackUnobservedTaskException);
21 | }
22 |
23 | protected Task LongTestDelay()
24 | {
25 | return Task.Delay(TimeSpan.FromSeconds(1));
26 | }
27 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/Clients/MqttClientOptionsBuilder_Tests.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Linq;
6 | using Microsoft.VisualStudio.TestTools.UnitTesting;
7 |
8 | namespace MQTTnet.Tests.Clients;
9 |
10 | // ReSharper disable InconsistentNaming
11 | [TestClass]
12 | public class MqttClientOptionsBuilder_Tests
13 | {
14 | [TestMethod]
15 | public void WithConnectionUri_Credential_Test()
16 | {
17 | var options = new MqttClientOptionsBuilder()
18 | .WithConnectionUri("mqtt://user:password@127.0.0.1")
19 | .Build();
20 |
21 | Assert.AreEqual("user", options.Credentials.GetUserName(null));
22 | Assert.IsTrue("password"u8.ToArray().SequenceEqual(options.Credentials.GetPassword(null)));
23 | }
24 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/Diagnostics/SourceLogger_Tests.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using MQTTnet.Diagnostics.Logger;
7 |
8 | namespace MQTTnet.Tests.Diagnostics;
9 |
10 | // ReSharper disable InconsistentNaming
11 | [TestClass]
12 | public sealed class SourceLogger_Tests : BaseTestClass
13 | {
14 | [TestMethod]
15 | public void Log_With_Source()
16 | {
17 | MqttNetLogMessage logMessage = null;
18 |
19 | var logger = new MqttNetEventLogger();
20 | logger.LogMessagePublished += (_, e) =>
21 | {
22 | logMessage = e.LogMessage;
23 | };
24 |
25 | var sourceLogger = logger.WithSource("The_Source");
26 | sourceLogger.Info("MESSAGE", (object)null, (object)null);
27 |
28 | Assert.AreEqual("The_Source", logMessage.Source);
29 | }
30 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/Helpers/MqttClientExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Tests.Mockups;
7 |
8 | namespace MQTTnet.Tests.Helpers;
9 |
10 | public static class MqttClientExtensions
11 | {
12 | public static TestApplicationMessageReceivedHandler TrackReceivedMessages(this IMqttClient client)
13 | {
14 | ArgumentNullException.ThrowIfNull(client);
15 |
16 | return new TestApplicationMessageReceivedHandler(client);
17 | }
18 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/Helpers/MqttPacketWriterExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Formatter;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Tests.Helpers;
9 |
10 | public static class MqttPacketWriterExtensions
11 | {
12 | public static byte[] AddMqttHeader(this MqttBufferWriter writer, MqttControlPacketType header, byte[] body)
13 | {
14 | writer.WriteByte(MqttBufferWriter.BuildFixedHeader(header));
15 | writer.WriteVariableByteInteger((uint)body.Length);
16 | writer.WriteBinary(body, 0, body.Length);
17 | return writer.GetBuffer();
18 | }
19 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/Helpers/ReflectionExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Reflection;
7 |
8 | namespace MQTTnet.Tests.Helpers;
9 |
10 | public static class ReflectionExtensions
11 | {
12 | public static object GetFieldValue(this object source, string fieldName)
13 | {
14 | ArgumentNullException.ThrowIfNull(source);
15 |
16 | var field = source.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
17 | if (field == null)
18 | {
19 | throw new ArgumentException($"Field {fieldName} not found.");
20 | }
21 |
22 | return field.GetValue(source);
23 | }
24 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/Internal/MqttPacketBusItem_Tests.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading.Tasks;
6 | using Microsoft.VisualStudio.TestTools.UnitTesting;
7 | using MQTTnet.Internal;
8 | using MQTTnet.Packets;
9 |
10 | namespace MQTTnet.Tests.Internal;
11 |
12 | // ReSharper disable InconsistentNaming
13 | [TestClass]
14 | public sealed class MqttPacketBusItem_Tests
15 | {
16 | [TestMethod]
17 | public void Fire_Completed_Event()
18 | {
19 | var eventFired = false;
20 |
21 | var item = new MqttPacketBusItem(new MqttPublishPacket());
22 | item.Completed += (_, _) =>
23 | {
24 | eventFired = true;
25 | };
26 |
27 | item.Complete();
28 |
29 | Assert.IsTrue(eventFired);
30 | }
31 |
32 | [TestMethod]
33 | [ExpectedException(typeof(TaskCanceledException))]
34 | public async Task Wait_Packet_Bus_Item_After_Already_Canceled()
35 | {
36 | var item = new MqttPacketBusItem(new MqttPublishPacket());
37 |
38 | // Finish the item before the actual
39 | item.Cancel();
40 |
41 | await item.WaitAsync().ConfigureAwait(false);
42 | }
43 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/Mockups/TestLogger.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Diagnostics.Logger;
7 |
8 | namespace MQTTnet.Tests.Mockups;
9 |
10 | public sealed class TestLogger : IMqttNetLogger
11 | {
12 | public event EventHandler LogMessagePublished;
13 |
14 | public bool IsEnabled { get; } = true;
15 |
16 | public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception)
17 | {
18 | LogMessagePublished?.Invoke(this, new MqttNetLogMessagePublishedEventArgs(new MqttNetLogMessage
19 | {
20 | Level = logLevel,
21 | Message = string.Format(message, parameters),
22 | Exception = exception
23 | }));
24 | }
25 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/MqttPacketIdentifierProvider_Tests.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 |
7 | namespace MQTTnet.Tests;
8 |
9 | // ReSharper disable InconsistentNaming
10 | [TestClass]
11 | public class MqttPacketIdentifierProvider_Tests
12 | {
13 | [TestMethod]
14 | public void Reset()
15 | {
16 | var p = new MqttPacketIdentifierProvider();
17 | Assert.AreEqual(1, p.GetNextPacketIdentifier());
18 | Assert.AreEqual(2, p.GetNextPacketIdentifier());
19 | p.Reset();
20 | Assert.AreEqual(1, p.GetNextPacketIdentifier());
21 | }
22 |
23 | [TestMethod]
24 | public void ReachBoundaries()
25 | {
26 | var p = new MqttPacketIdentifierProvider();
27 |
28 | for (ushort i = 0; i < ushort.MaxValue; i++)
29 | {
30 | Assert.AreEqual(i + 1, p.GetNextPacketIdentifier());
31 | }
32 |
33 | Assert.AreEqual(1, p.GetNextPacketIdentifier());
34 | }
35 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/MqttPacketWriter_Tests.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using MQTTnet.Formatter;
7 |
8 | namespace MQTTnet.Tests;
9 |
10 | // ReSharper disable InconsistentNaming
11 | [TestClass]
12 | public class MqttPacketWriter_Tests
13 | {
14 | protected virtual MqttBufferWriter WriterFactory()
15 | {
16 | return new MqttBufferWriter(4096, 65535);
17 | }
18 |
19 | [TestMethod]
20 | public void WritePacket()
21 | {
22 | var writer = WriterFactory();
23 | Assert.AreEqual(0, writer.Length);
24 |
25 | writer.WriteString("1234567890");
26 | Assert.AreEqual(10 + 2, writer.Length);
27 |
28 | writer.WriteBinary(new byte[300]);
29 | Assert.AreEqual(300 + 2 + 12, writer.Length);
30 |
31 | writer.WriteBinary(new byte[5000]);
32 | Assert.AreEqual(5000 + 2 + 300 + 2 + 12, writer.Length);
33 | }
34 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/MqttTopicValidator_Tests.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using MQTTnet.Exceptions;
7 | using MQTTnet.Protocol;
8 |
9 | namespace MQTTnet.Tests;
10 |
11 | // ReSharper disable InconsistentNaming
12 | [TestClass]
13 | public sealed class MqttTopicValidator_Tests
14 | {
15 | [TestMethod]
16 | [ExpectedException(typeof(MqttProtocolViolationException))]
17 | public void Invalid_Topic_Empty()
18 | {
19 | MqttTopicValidator.ThrowIfInvalid(string.Empty);
20 | }
21 |
22 | [TestMethod]
23 | [ExpectedException(typeof(MqttProtocolViolationException))]
24 | public void Invalid_Topic_Hash()
25 | {
26 | MqttTopicValidator.ThrowIfInvalid("/a/#/c");
27 | }
28 |
29 | [TestMethod]
30 | [ExpectedException(typeof(MqttProtocolViolationException))]
31 | public void Invalid_Topic_Plus()
32 | {
33 | MqttTopicValidator.ThrowIfInvalid("/a/+/c");
34 | }
35 |
36 | [TestMethod]
37 | public void Valid_Topic()
38 | {
39 | MqttTopicValidator.ThrowIfInvalid("/a/b/c");
40 | }
41 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/Server/MqttRetainedMessageManager_Tests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 | using System.Threading.Tasks;
3 | using MQTTnet.Server.Internal;
4 |
5 | namespace MQTTnet.Tests.Server;
6 |
7 | // ReSharper disable InconsistentNaming
8 | [TestClass]
9 | public sealed class MqttRetainedMessageManager_Tests
10 | {
11 | [TestMethod]
12 | public async Task MqttRetainedMessageManager_GetUndefinedTopic()
13 | {
14 | var logger = new Mockups.TestLogger();
15 | var eventContainer = new MqttServerEventContainer();
16 | var retainedMessagesManager = new MqttRetainedMessagesManager(eventContainer, logger);
17 | var task = retainedMessagesManager.GetMessage("undefined");
18 | Assert.IsNotNull(task, "Task should not be null");
19 | var result = await task;
20 | Assert.IsNull(result, "Null result expected");
21 | }
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet.Tests/Server/Server_Reference_Tests.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading.Tasks;
6 | using Microsoft.VisualStudio.TestTools.UnitTesting;
7 | using MQTTnet.Formatter;
8 | using MQTTnet.Internal;
9 | using MQTTnet.Protocol;
10 |
11 | namespace MQTTnet.Tests.Server;
12 |
13 | // ReSharper disable InconsistentNaming
14 | [TestClass]
15 | public sealed class Server_Reference_Tests : BaseTestClass
16 | {
17 | [TestMethod]
18 | public async Task Server_Reports_With_Reference_Server()
19 | {
20 | using var testEnvironment = CreateTestEnvironment();
21 | testEnvironment.IgnoreClientLogErrors = true;
22 |
23 | var server = await testEnvironment.StartServer();
24 |
25 | server.ValidatingConnectionAsync += e =>
26 | {
27 | e.ReasonCode = MqttConnectReasonCode.ServerMoved;
28 | e.ServerReference = "new_server";
29 | return CompletedTask.Instance;
30 | };
31 |
32 | var client = testEnvironment.CreateClient();
33 |
34 | var response = await client.ConnectAsync(
35 | new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500).WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
36 |
37 | Assert.AreEqual(MqttClientConnectResultCode.ServerMoved, response.ResultCode);
38 | Assert.AreEqual("new_server", response.ServerReference);
39 | }
40 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Adapter/IMqttChannelAdapter.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Net;
7 | using System.Security.Cryptography.X509Certificates;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 | using MQTTnet.Formatter;
11 | using MQTTnet.Packets;
12 |
13 | namespace MQTTnet.Adapter;
14 |
15 | public interface IMqttChannelAdapter : IDisposable
16 | {
17 | long BytesReceived { get; }
18 |
19 | long BytesSent { get; }
20 |
21 | X509Certificate2 ClientCertificate { get; }
22 |
23 | EndPoint RemoteEndPoint { get; }
24 |
25 | bool IsSecureConnection { get; }
26 |
27 | MqttPacketFormatterAdapter PacketFormatterAdapter { get; }
28 |
29 | Task ConnectAsync(CancellationToken cancellationToken);
30 |
31 | Task DisconnectAsync(CancellationToken cancellationToken);
32 |
33 | Task ReceivePacketAsync(CancellationToken cancellationToken);
34 |
35 | void ResetStatistics();
36 |
37 | Task SendPacketAsync(MqttPacket packet, CancellationToken cancellationToken);
38 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Adapter/IMqttClientAdapterFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Diagnostics.Logger;
6 |
7 | namespace MQTTnet.Adapter;
8 |
9 | public interface IMqttClientAdapterFactory
10 | {
11 | IMqttChannelAdapter CreateClientAdapter(MqttClientOptions options, MqttPacketInspector packetInspector, IMqttNetLogger logger);
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Adapter/MqttConnectingFailedException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Exceptions;
7 |
8 | namespace MQTTnet.Adapter;
9 |
10 | public sealed class MqttConnectingFailedException : MqttCommunicationException
11 | {
12 | public MqttConnectingFailedException(string message, Exception innerException) : base(message, innerException)
13 | {
14 | }
15 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Adapter/ReceivedMqttPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Adapter;
8 |
9 | public readonly struct ReceivedMqttPacket
10 | {
11 | public static readonly ReceivedMqttPacket Empty;
12 |
13 | public ReceivedMqttPacket(byte fixedHeader, ArraySegment body, int totalLength)
14 | {
15 | FixedHeader = fixedHeader;
16 | Body = body;
17 | TotalLength = totalLength;
18 | }
19 |
20 | public byte FixedHeader { get; }
21 |
22 | public ArraySegment Body { get; }
23 |
24 | public int TotalLength { get; }
25 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Certificates/BlobCertificateProvider.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Security.Cryptography.X509Certificates;
7 |
8 | namespace MQTTnet.Certificates;
9 |
10 | public class BlobCertificateProvider(byte[] blob) : ICertificateProvider
11 | {
12 | public byte[] Blob { get; } = blob ?? throw new ArgumentNullException(nameof(blob));
13 |
14 | public string Password { get; set; }
15 |
16 | public X509Certificate2 GetCertificate()
17 | {
18 | if (string.IsNullOrEmpty(Password))
19 | {
20 | // Use a different overload when no password is specified. Otherwise, the constructor will fail.
21 | return new X509Certificate2(Blob);
22 | }
23 |
24 | return new X509Certificate2(Blob, Password);
25 | }
26 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Certificates/ICertificateProvider.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Security.Cryptography.X509Certificates;
6 |
7 | namespace MQTTnet.Certificates;
8 |
9 | public interface ICertificateProvider
10 | {
11 | X509Certificate2 GetCertificate();
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Certificates/X509CertificateProvider.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Security.Cryptography.X509Certificates;
7 |
8 | namespace MQTTnet.Certificates;
9 |
10 | public class X509CertificateProvider(X509Certificate2 certificate) : ICertificateProvider
11 | {
12 | readonly X509Certificate2 _certificate = certificate ?? throw new ArgumentNullException(nameof(certificate));
13 |
14 | public X509Certificate2 GetCertificate()
15 | {
16 | return _certificate;
17 | }
18 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Channel/IMqttChannel.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Buffers;
7 | using System.Net;
8 | using System.Security.Cryptography.X509Certificates;
9 | using System.Threading;
10 | using System.Threading.Tasks;
11 |
12 | namespace MQTTnet.Channel;
13 |
14 | public interface IMqttChannel : IDisposable
15 | {
16 | X509Certificate2 ClientCertificate { get; }
17 | EndPoint RemoteEndPoint { get; }
18 |
19 | bool IsSecureConnection { get; }
20 |
21 | Task ConnectAsync(CancellationToken cancellationToken);
22 |
23 | Task DisconnectAsync(CancellationToken cancellationToken);
24 |
25 | Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken);
26 |
27 | Task WriteAsync(ReadOnlySequence buffer, bool isEndOfPacket, CancellationToken cancellationToken);
28 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Connecting/MqttClientConnectResultCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public enum MqttClientConnectResultCode
8 | {
9 | Success = 0,
10 | UnspecifiedError = 128,
11 | MalformedPacket = 129,
12 | ProtocolError = 130,
13 | ImplementationSpecificError = 131,
14 | UnsupportedProtocolVersion = 132,
15 | ClientIdentifierNotValid = 133,
16 | BadUserNameOrPassword = 134,
17 | NotAuthorized = 135,
18 | ServerUnavailable = 136,
19 | ServerBusy = 137,
20 | Banned = 138,
21 | BadAuthenticationMethod = 140,
22 | TopicNameInvalid = 144,
23 | PacketTooLarge = 149,
24 | QuotaExceeded = 151,
25 | PayloadFormatInvalid = 153,
26 | RetainNotSupported = 154,
27 | QoSNotSupported = 155,
28 | UseAnotherServer = 156,
29 | ServerMoved = 157,
30 | ConnectionRateExceeded = 159
31 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Connecting/MqttClientConnectedEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet;
8 |
9 | public sealed class MqttClientConnectedEventArgs : EventArgs
10 | {
11 | public MqttClientConnectedEventArgs(MqttClientConnectResult connectResult)
12 | {
13 | ConnectResult = connectResult ?? throw new ArgumentNullException(nameof(connectResult));
14 | }
15 |
16 | ///
17 | /// Gets the authentication result.
18 | /// MQTT 5.0.0+ feature.
19 | ///
20 | public MqttClientConnectResult ConnectResult { get; }
21 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Connecting/MqttClientConnectingEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet;
8 |
9 | public sealed class MqttClientConnectingEventArgs : EventArgs
10 | {
11 | public MqttClientConnectingEventArgs(MqttClientOptions clientOptions)
12 | {
13 | ClientOptions = clientOptions;
14 | }
15 |
16 | public MqttClientOptions ClientOptions { get; }
17 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Diagnostics/Logger/IMqttNetLogger.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Diagnostics.Logger;
8 |
9 | public interface IMqttNetLogger
10 | {
11 | bool IsEnabled { get; }
12 |
13 | void Publish(MqttNetLogLevel level, string source, string message, object[] parameters, Exception exception);
14 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Diagnostics/Logger/MqttNetLogLevel.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Diagnostics.Logger;
6 |
7 | public enum MqttNetLogLevel
8 | {
9 | Verbose,
10 |
11 | Info,
12 |
13 | Warning,
14 |
15 | Error
16 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Diagnostics/Logger/MqttNetLogMessage.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Diagnostics.Logger;
8 |
9 | public sealed class MqttNetLogMessage
10 | {
11 | public string LogId { get; set; }
12 |
13 | public DateTime Timestamp { get; set; }
14 |
15 | public int ThreadId { get; set; }
16 |
17 | public string Source { get; set; }
18 |
19 | public MqttNetLogLevel Level { get; set; }
20 |
21 | public string Message { get; set; }
22 |
23 | public Exception Exception { get; set; }
24 |
25 | public override string ToString()
26 | {
27 | var result = $"[{Timestamp:O}] [{LogId}] [{ThreadId}] [{Source}] [{Level}]: {Message}";
28 | if (Exception != null)
29 | {
30 | result += Environment.NewLine + Exception;
31 | }
32 |
33 | return result;
34 | }
35 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Diagnostics/Logger/MqttNetLogMessagePublishedEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Diagnostics.Logger;
8 |
9 | public sealed class MqttNetLogMessagePublishedEventArgs(MqttNetLogMessage logMessage) : EventArgs
10 | {
11 | public MqttNetLogMessage LogMessage { get; } = logMessage ?? throw new ArgumentNullException(nameof(logMessage));
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Diagnostics/Logger/MqttNetNullLogger.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Diagnostics.Logger;
8 |
9 | ///
10 | /// This logger does nothing with the messages.
11 | ///
12 | public sealed class MqttNetNullLogger : IMqttNetLogger
13 | {
14 | public static MqttNetNullLogger Instance { get; } = new();
15 |
16 | public bool IsEnabled { get; }
17 |
18 | public void Publish(MqttNetLogLevel level, string source, string message, object[] parameters, Exception exception)
19 | {
20 | }
21 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Diagnostics/Logger/MqttNetSourceLogger.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Diagnostics.Logger;
8 |
9 | public sealed class MqttNetSourceLogger(IMqttNetLogger logger, string source)
10 | {
11 | readonly IMqttNetLogger _logger = logger ?? throw new ArgumentNullException(nameof(logger));
12 |
13 | public bool IsEnabled => _logger.IsEnabled;
14 |
15 | public void Publish(MqttNetLogLevel logLevel, string message, object[] parameters, Exception exception)
16 | {
17 | _logger.Publish(logLevel, source, message, parameters, exception);
18 | }
19 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Diagnostics/PacketInspection/InspectMqttPacketEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Diagnostics.PacketInspection;
8 |
9 | public sealed class InspectMqttPacketEventArgs : EventArgs
10 | {
11 | public InspectMqttPacketEventArgs(MqttPacketFlowDirection direction, byte[] buffer)
12 | {
13 | Direction = direction;
14 | Buffer = buffer ?? throw new ArgumentNullException(nameof(buffer));
15 | }
16 |
17 | public byte[] Buffer { get; }
18 |
19 | public MqttPacketFlowDirection Direction { get; }
20 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Diagnostics/PacketInspection/MqttPacketFlowDirection.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Diagnostics.PacketInspection;
6 |
7 | public enum MqttPacketFlowDirection
8 | {
9 | Inbound,
10 |
11 | Outbound
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Disconnecting/MqttClientDisconnectOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MQTTnet.Packets;
7 |
8 | namespace MQTTnet;
9 |
10 | public sealed class MqttClientDisconnectOptions
11 | {
12 | ///
13 | /// Gets or sets the reason code.
14 | /// MQTT 5.0.0+ feature.
15 | ///
16 | public MqttClientDisconnectOptionsReason Reason { get; set; } = MqttClientDisconnectOptionsReason.NormalDisconnection;
17 |
18 | ///
19 | /// Gets or sets the reason string.
20 | /// MQTT 5.0.0+ feature.
21 | ///
22 | public string ReasonString { get; set; }
23 |
24 | ///
25 | /// Gets or sets the session expiry interval.
26 | /// MQTT 5.0.0+ feature.
27 | ///
28 | public uint SessionExpiryInterval { get; set; }
29 |
30 | ///
31 | /// Gets or sets the user properties.
32 | /// MQTT 5.0.0+ feature.
33 | ///
34 | public List UserProperties { get; set; }
35 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Disconnecting/MqttClientDisconnectOptionsReason.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | ///
8 | /// This enum only contains values which are valid when a client sends the reason to the server.
9 | ///
10 | public enum MqttClientDisconnectOptionsReason
11 | {
12 | NormalDisconnection = 0,
13 | DisconnectWithWillMessage = 4,
14 | UnspecifiedError = 128,
15 | MalformedPacket = 129,
16 | ProtocolError = 130,
17 | ImplementationSpecificError = 131,
18 | TopicNameInvalid = 144,
19 | ReceiveMaximumExceeded = 147,
20 | TopicAliasInvalid = 148,
21 | PacketTooLarge = 149,
22 | MessageRateTooHigh = 150,
23 | QuotaExceeded = 151,
24 | AdministrativeAction = 152,
25 | PayloadFormatInvalid = 153
26 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Disconnecting/MqttClientDisconnectOptionsValidator.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Formatter;
7 |
8 | namespace MQTTnet;
9 |
10 | public static class MqttClientDisconnectOptionsValidator
11 | {
12 | public static void ThrowIfNotSupported(MqttClientDisconnectOptions options, MqttProtocolVersion protocolVersion)
13 | {
14 | ArgumentNullException.ThrowIfNull(options);
15 |
16 | if (protocolVersion == MqttProtocolVersion.V500)
17 | {
18 | // Everything is supported.
19 | return;
20 | }
21 |
22 | if (options.ReasonString?.Length > 0)
23 | {
24 | Throw(nameof(options.ReasonString));
25 | }
26 |
27 | if (options.Reason != MqttClientDisconnectOptionsReason.NormalDisconnection)
28 | {
29 | Throw(nameof(options.Reason));
30 | }
31 | }
32 |
33 | static void Throw(string featureName)
34 | {
35 | throw new NotSupportedException($"Feature {featureName} requires MQTT version 5.0.0.");
36 | }
37 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Disconnecting/MqttClientDisconnectReason.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public enum MqttClientDisconnectReason
8 | {
9 | NormalDisconnection = 0,
10 | DisconnectWithWillMessage = 4,
11 | UnspecifiedError = 128,
12 | MalformedPacket = 129,
13 | ProtocolError = 130,
14 | ImplementationSpecificError = 131,
15 | NotAuthorized = 135,
16 | ServerBusy = 137,
17 | ServerShuttingDown = 139,
18 | BadAuthenticationMethod = 140,
19 | KeepAliveTimeout = 141,
20 | SessionTakenOver = 142,
21 | TopicFilterInvalid = 143,
22 | TopicNameInvalid = 144,
23 | ReceiveMaximumExceeded = 147,
24 | TopicAliasInvalid = 148,
25 | PacketTooLarge = 149,
26 | MessageRateTooHigh = 150,
27 | QuotaExceeded = 151,
28 | AdministrativeAction = 152,
29 | PayloadFormatInvalid = 153,
30 | RetainNotSupported = 154,
31 | QosNotSupported = 155,
32 | UseAnotherServer = 156,
33 | ServerMoved = 157,
34 | SharedSubscriptionsNotSupported = 158,
35 | ConnectionRateExceeded = 159,
36 | MaximumConnectTime = 160,
37 | SubscriptionIdentifiersNotSupported = 161,
38 | WildcardSubscriptionsNotSupported = 162
39 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Disconnecting/MqttClientDisconnectedEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using MQTTnet.Packets;
8 |
9 | namespace MQTTnet;
10 |
11 | public sealed class MqttClientDisconnectedEventArgs : EventArgs
12 | {
13 | public MqttClientDisconnectedEventArgs(
14 | bool clientWasConnected,
15 | MqttClientConnectResult connectResult,
16 | MqttClientDisconnectReason reason,
17 | string reasonString,
18 | List userProperties,
19 | Exception exception)
20 | {
21 | ClientWasConnected = clientWasConnected;
22 | ConnectResult = connectResult;
23 | Exception = exception;
24 | Reason = reason;
25 | ReasonString = reasonString;
26 | UserProperties = userProperties;
27 | }
28 |
29 | public bool ClientWasConnected { get; }
30 |
31 | ///
32 | /// Gets the authentication result.
33 | /// MQTT 5.0.0+ feature.
34 | ///
35 | public MqttClientConnectResult ConnectResult { get; }
36 |
37 | public Exception Exception { get; }
38 |
39 | ///
40 | /// Gets or sets the reason.
41 | /// MQTT 5.0.0+ feature.
42 | ///
43 | public MqttClientDisconnectReason Reason { get; }
44 |
45 | public string ReasonString { get; }
46 |
47 | public List UserProperties { get; }
48 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Exceptions/MqttClientDisconnectedException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Exceptions;
8 |
9 | public sealed class MqttClientDisconnectedException : MqttCommunicationException
10 | {
11 | public MqttClientDisconnectedException(Exception innerException) : base("The MQTT client is disconnected.", innerException)
12 | {
13 | }
14 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Exceptions/MqttClientNotConnectedException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Exceptions;
6 |
7 | public class MqttClientNotConnectedException : MqttCommunicationException
8 | {
9 | public MqttClientNotConnectedException() : base("The MQTT client is not connected.")
10 | {
11 | }
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Exceptions/MqttClientUnexpectedDisconnectReceivedException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using MQTTnet.Packets;
8 | using MQTTnet.Protocol;
9 |
10 | namespace MQTTnet.Exceptions;
11 |
12 | public sealed class MqttClientUnexpectedDisconnectReceivedException(MqttDisconnectPacket disconnectPacket, Exception innerException = null) : MqttCommunicationException(
13 | $"Unexpected DISCONNECT (Reason code={disconnectPacket.ReasonCode}) received.",
14 | innerException)
15 | {
16 | public MqttDisconnectReasonCode? ReasonCode { get; } = disconnectPacket.ReasonCode;
17 |
18 | public string ReasonString { get; } = disconnectPacket.ReasonString;
19 |
20 | public string ServerReference { get; } = disconnectPacket.ServerReference;
21 |
22 | public uint? SessionExpiryInterval { get; } = disconnectPacket.SessionExpiryInterval;
23 |
24 | public List UserProperties { get; } = disconnectPacket.UserProperties;
25 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Exceptions/MqttCommunicationException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Exceptions;
8 |
9 | public class MqttCommunicationException : Exception
10 | {
11 | public MqttCommunicationException(Exception innerException)
12 | : base(innerException?.Message ?? "MQTT communication failed.", innerException)
13 | {
14 | }
15 |
16 | public MqttCommunicationException(string message, Exception innerException = null)
17 | : base(message, innerException)
18 | {
19 | }
20 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Exceptions/MqttCommunicationTimedOutException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Exceptions;
8 |
9 | public sealed class MqttCommunicationTimedOutException : MqttCommunicationException
10 | {
11 | public MqttCommunicationTimedOutException() : base("The operation has timed out.")
12 | {
13 | }
14 |
15 | public MqttCommunicationTimedOutException(Exception innerException) : base("The operation has timed out.", innerException)
16 | {
17 | }
18 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Exceptions/MqttConfigurationException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Exceptions;
8 |
9 | public class MqttConfigurationException : Exception
10 | {
11 | protected MqttConfigurationException()
12 | {
13 | }
14 |
15 | public MqttConfigurationException(Exception innerException)
16 | : base(innerException.Message, innerException)
17 | {
18 | }
19 |
20 | public MqttConfigurationException(string message)
21 | : base(message)
22 | {
23 | }
24 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Exceptions/MqttProtocolViolationException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Exceptions;
8 |
9 | public class MqttProtocolViolationException(string message) : Exception(message);
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/IMqttPacketFormatter.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Adapter;
6 | using MQTTnet.Packets;
7 |
8 | namespace MQTTnet.Formatter;
9 |
10 | public interface IMqttPacketFormatter
11 | {
12 | MqttPacket Decode(ReceivedMqttPacket receivedPacket);
13 |
14 | MqttPacketBuffer Encode(MqttPacket packet);
15 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttApplicationMessageFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Packets;
7 |
8 | namespace MQTTnet.Formatter;
9 |
10 | public static class MqttApplicationMessageFactory
11 | {
12 | public static MqttApplicationMessage Create(MqttPublishPacket publishPacket)
13 | {
14 | ArgumentNullException.ThrowIfNull(publishPacket);
15 |
16 | return new MqttApplicationMessage
17 | {
18 | Topic = publishPacket.Topic,
19 | Payload = publishPacket.Payload,
20 | QualityOfServiceLevel = publishPacket.QualityOfServiceLevel,
21 | Retain = publishPacket.Retain,
22 | Dup = publishPacket.Dup,
23 | ResponseTopic = publishPacket.ResponseTopic,
24 | ContentType = publishPacket.ContentType,
25 | CorrelationData = publishPacket.CorrelationData,
26 | MessageExpiryInterval = publishPacket.MessageExpiryInterval,
27 | SubscriptionIdentifiers = publishPacket.SubscriptionIdentifiers,
28 | TopicAlias = publishPacket.TopicAlias,
29 | PayloadFormatIndicator = publishPacket.PayloadFormatIndicator,
30 | UserProperties = publishPacket.UserProperties
31 | };
32 | }
33 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttDisconnectPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Formatter;
9 |
10 | public static class MqttDisconnectPacketFactory
11 | {
12 | static readonly MqttDisconnectPacket DefaultNormalDisconnection = new()
13 | {
14 | ReasonCode = MqttDisconnectReasonCode.NormalDisconnection,
15 | UserProperties = null,
16 | ReasonString = null,
17 | ServerReference = null,
18 | SessionExpiryInterval = 0
19 | };
20 |
21 | public static MqttDisconnectPacket Create(MqttClientDisconnectOptions clientDisconnectOptions)
22 | {
23 | if (clientDisconnectOptions == null)
24 | {
25 | return DefaultNormalDisconnection;
26 | }
27 |
28 | return new MqttDisconnectPacket
29 | {
30 | ReasonCode = (MqttDisconnectReasonCode)clientDisconnectOptions.Reason,
31 | UserProperties = clientDisconnectOptions.UserProperties,
32 | SessionExpiryInterval = clientDisconnectOptions.SessionExpiryInterval
33 | };
34 | }
35 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttFixedHeader.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Formatter;
6 |
7 | public struct MqttFixedHeader(byte flags, int remainingLength, int totalLength)
8 | {
9 | public byte Flags { get; } = flags;
10 |
11 | public int RemainingLength { get; } = remainingLength;
12 |
13 | public int TotalLength { get; } = totalLength;
14 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttPacketBuffer.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Internal;
6 | using System;
7 | using System.Buffers;
8 |
9 | namespace MQTTnet.Formatter;
10 |
11 | public readonly struct MqttPacketBuffer
12 | {
13 | public MqttPacketBuffer(ArraySegment packet, ReadOnlySequence payload)
14 | {
15 | Packet = packet;
16 | Payload = payload;
17 |
18 | Length = Packet.Count + (int)Payload.Length;
19 | }
20 |
21 | public MqttPacketBuffer(ArraySegment packet)
22 | {
23 | Packet = packet;
24 | Payload = EmptyBuffer.ReadOnlySequence;
25 |
26 | Length = Packet.Count;
27 | }
28 |
29 | public int Length { get; }
30 |
31 | public ArraySegment Packet { get; }
32 |
33 | public ReadOnlySequence Payload { get; }
34 |
35 | public byte[] ToArray()
36 | {
37 | if (Payload.Length == 0)
38 | {
39 | return Packet.ToArray();
40 | }
41 |
42 | var buffer = GC.AllocateUninitializedArray(Length);
43 | MqttMemoryHelper.Copy(Packet.Array, Packet.Offset, buffer, 0, Packet.Count);
44 | MqttMemoryHelper.Copy(Payload, 0, buffer, Packet.Count, (int)Payload.Length);
45 |
46 | return buffer;
47 | }
48 |
49 | public ArraySegment Join()
50 | {
51 | if (Payload.Length == 0)
52 | {
53 | return Packet;
54 | }
55 |
56 | return new ArraySegment(ToArray());
57 | }
58 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttProtocolVersion.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Formatter;
6 |
7 | public enum MqttProtocolVersion
8 | {
9 | Unknown = 0,
10 |
11 | V310 = 3,
12 | V311 = 4,
13 | V500 = 5
14 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttPubAckPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Packets;
7 | using MQTTnet.Protocol;
8 |
9 | namespace MQTTnet.Formatter;
10 |
11 | public static class MqttPubAckPacketFactory
12 | {
13 | public static MqttPubAckPacket Create(MqttApplicationMessageReceivedEventArgs applicationMessageReceivedEventArgs)
14 | {
15 | ArgumentNullException.ThrowIfNull(applicationMessageReceivedEventArgs);
16 |
17 | var pubAckPacket = new MqttPubAckPacket
18 | {
19 | PacketIdentifier = applicationMessageReceivedEventArgs.PublishPacket.PacketIdentifier,
20 | ReasonCode = (MqttPubAckReasonCode)(int)applicationMessageReceivedEventArgs.ReasonCode,
21 | UserProperties = applicationMessageReceivedEventArgs.ResponseUserProperties,
22 | ReasonString = applicationMessageReceivedEventArgs.ResponseReasonString
23 | };
24 |
25 | return pubAckPacket;
26 | }
27 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttPubCompPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Packets;
7 | using MQTTnet.Protocol;
8 |
9 | namespace MQTTnet.Formatter;
10 |
11 | public static class MqttPubCompPacketFactory
12 | {
13 | public static MqttPubCompPacket Create(MqttPubRelPacket pubRelPacket, MqttApplicationMessageReceivedReasonCode reasonCode)
14 | {
15 | ArgumentNullException.ThrowIfNull(pubRelPacket);
16 |
17 | return new MqttPubCompPacket
18 | {
19 | PacketIdentifier = pubRelPacket.PacketIdentifier,
20 | ReasonCode = (MqttPubCompReasonCode)(int)reasonCode
21 | };
22 | }
23 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttPubRecPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Packets;
7 | using MQTTnet.Protocol;
8 |
9 | namespace MQTTnet.Formatter;
10 |
11 | public static class MqttPubRecPacketFactory
12 | {
13 | public static MqttPubRecPacket Create(MqttApplicationMessageReceivedEventArgs applicationMessageReceivedEventArgs)
14 | {
15 | ArgumentNullException.ThrowIfNull(applicationMessageReceivedEventArgs);
16 |
17 | var pubRecPacket = Create(applicationMessageReceivedEventArgs.PublishPacket, applicationMessageReceivedEventArgs.ReasonCode);
18 | pubRecPacket.UserProperties = applicationMessageReceivedEventArgs.ResponseUserProperties;
19 |
20 | return pubRecPacket;
21 | }
22 |
23 | static MqttPubRecPacket Create(MqttPublishPacket publishPacket, MqttApplicationMessageReceivedReasonCode applicationMessageReceivedReasonCode)
24 | {
25 | var pubRecPacket = new MqttPubRecPacket
26 | {
27 | PacketIdentifier = publishPacket.PacketIdentifier,
28 | ReasonCode = (MqttPubRecReasonCode)(int)applicationMessageReceivedReasonCode
29 | };
30 |
31 | return pubRecPacket;
32 | }
33 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttPubRelPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Packets;
7 | using MQTTnet.Protocol;
8 |
9 | namespace MQTTnet.Formatter;
10 |
11 | public static class MqttPubRelPacketFactory
12 | {
13 | public static MqttPubRelPacket Create(MqttPubRecPacket pubRecPacket, MqttApplicationMessageReceivedReasonCode reasonCode)
14 | {
15 | ArgumentNullException.ThrowIfNull(pubRecPacket);
16 |
17 | return new MqttPubRelPacket
18 | {
19 | PacketIdentifier = pubRecPacket.PacketIdentifier,
20 | ReasonCode = (MqttPubRelReasonCode)(int)reasonCode
21 | };
22 | }
23 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttPublishPacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Packets;
7 |
8 | namespace MQTTnet.Formatter;
9 |
10 | public static class MqttPublishPacketFactory
11 | {
12 | public static MqttPublishPacket Create(MqttApplicationMessage applicationMessage)
13 | {
14 | ArgumentNullException.ThrowIfNull(applicationMessage);
15 |
16 | // Copy all values to their matching counterparts.
17 | // The not supported values in MQTT 3.1.1 are not serialized (excluded) later.
18 | var packet = new MqttPublishPacket
19 | {
20 | Topic = applicationMessage.Topic,
21 | Payload = applicationMessage.Payload,
22 | QualityOfServiceLevel = applicationMessage.QualityOfServiceLevel,
23 | Retain = applicationMessage.Retain,
24 | Dup = applicationMessage.Dup,
25 | ContentType = applicationMessage.ContentType,
26 | CorrelationData = applicationMessage.CorrelationData,
27 | MessageExpiryInterval = applicationMessage.MessageExpiryInterval,
28 | PayloadFormatIndicator = applicationMessage.PayloadFormatIndicator,
29 | ResponseTopic = applicationMessage.ResponseTopic,
30 | TopicAlias = applicationMessage.TopicAlias,
31 | SubscriptionIdentifiers = applicationMessage.SubscriptionIdentifiers,
32 | UserProperties = applicationMessage.UserProperties
33 | };
34 |
35 | return packet;
36 | }
37 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttSubscribePacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Packets;
7 |
8 | namespace MQTTnet.Formatter;
9 |
10 | public static class MqttSubscribePacketFactory
11 | {
12 | public static MqttSubscribePacket Create(MqttClientSubscribeOptions clientSubscribeOptions)
13 | {
14 | ArgumentNullException.ThrowIfNull(clientSubscribeOptions);
15 |
16 | var packet = new MqttSubscribePacket
17 | {
18 | TopicFilters = clientSubscribeOptions.TopicFilters,
19 | SubscriptionIdentifier = clientSubscribeOptions.SubscriptionIdentifier,
20 | UserProperties = clientSubscribeOptions.UserProperties
21 | };
22 |
23 | return packet;
24 | }
25 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/MqttUnsubscribePacketFactory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Packets;
7 |
8 | namespace MQTTnet.Formatter;
9 |
10 | public static class MqttUnsubscribePacketFactory
11 | {
12 | public static MqttUnsubscribePacket Create(MqttClientUnsubscribeOptions clientUnsubscribeOptions)
13 | {
14 | ArgumentNullException.ThrowIfNull(clientUnsubscribeOptions);
15 |
16 | var packet = new MqttUnsubscribePacket
17 | {
18 | UserProperties = clientUnsubscribeOptions.UserProperties
19 | };
20 |
21 | if (clientUnsubscribeOptions.TopicFilters != null)
22 | {
23 | packet.TopicFilters.AddRange(clientUnsubscribeOptions.TopicFilters);
24 | }
25 |
26 | return packet;
27 | }
28 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/ReadFixedHeaderResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Formatter;
6 |
7 | public struct ReadFixedHeaderResult
8 | {
9 | public static ReadFixedHeaderResult Canceled { get; } = new()
10 | {
11 | IsCanceled = true
12 | };
13 |
14 | public static ReadFixedHeaderResult ConnectionClosed { get; } = new()
15 | {
16 | IsConnectionClosed = true
17 | };
18 |
19 | public bool IsCanceled { get; set; }
20 |
21 | public bool IsConnectionClosed { get; init; }
22 |
23 | public MqttFixedHeader FixedHeader { get; init; }
24 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Formatter/V5/MqttV5PacketFormatter.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Adapter;
6 | using MQTTnet.Packets;
7 |
8 | namespace MQTTnet.Formatter.V5;
9 |
10 | public sealed class MqttV5PacketFormatter : IMqttPacketFormatter
11 | {
12 | readonly MqttV5PacketDecoder _decoder;
13 | readonly MqttV5PacketEncoder _encoder;
14 |
15 | public MqttV5PacketFormatter(MqttBufferWriter bufferWriter)
16 | {
17 | _decoder = new MqttV5PacketDecoder();
18 | _encoder = new MqttV5PacketEncoder(bufferWriter);
19 | }
20 |
21 | public MqttPacket Decode(ReceivedMqttPacket receivedPacket)
22 | {
23 | return _decoder.Decode(receivedPacket);
24 | }
25 |
26 | public MqttPacketBuffer Encode(MqttPacket packet)
27 | {
28 | return _encoder.Encode(packet);
29 | }
30 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/IMqttClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using MQTTnet.Diagnostics.PacketInspection;
5 |
6 | namespace MQTTnet;
7 |
8 | public interface IMqttClient : IDisposable
9 | {
10 | event Func ApplicationMessageReceivedAsync;
11 |
12 | event Func ConnectedAsync;
13 |
14 | event Func ConnectingAsync;
15 |
16 | event Func DisconnectedAsync;
17 |
18 | event Func InspectPacketAsync;
19 |
20 | bool IsConnected { get; }
21 |
22 | MqttClientOptions Options { get; }
23 |
24 | Task ConnectAsync(MqttClientOptions options, CancellationToken cancellationToken = default);
25 |
26 | Task DisconnectAsync(MqttClientDisconnectOptions options, CancellationToken cancellationToken = default);
27 |
28 | Task PingAsync(CancellationToken cancellationToken = default);
29 |
30 | Task PublishAsync(MqttApplicationMessage applicationMessage, CancellationToken cancellationToken = default);
31 |
32 | Task SendEnhancedAuthenticationExchangeDataAsync(MqttEnhancedAuthenticationExchangeData data, CancellationToken cancellationToken = default);
33 |
34 | Task SubscribeAsync(MqttClientSubscribeOptions options, CancellationToken cancellationToken = default);
35 |
36 | Task UnsubscribeAsync(MqttClientUnsubscribeOptions options, CancellationToken cancellationToken = default);
37 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/InjectMqttApplicationMessageResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public class InjectMqttApplicationMessageResult
8 | {
9 | public ushort PacketIdentifier { get; init; }
10 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Internal/AsyncEventInvocator.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Threading.Tasks;
7 |
8 | namespace MQTTnet.Internal;
9 |
10 | public readonly struct AsyncEventInvocator
11 | {
12 | readonly Action _handler;
13 | readonly Func _asyncHandler;
14 |
15 | public AsyncEventInvocator(Action handler, Func asyncHandler)
16 | {
17 | _handler = handler;
18 | _asyncHandler = asyncHandler;
19 | }
20 |
21 | public bool WrapsHandler(Action handler1)
22 | {
23 | // Do not use ReferenceEquals! It will not work with delegates.
24 | return handler1 == _handler;
25 | }
26 |
27 | public bool WrapsHandler(Func handler)
28 | {
29 | // Do not use ReferenceEquals! It will not work with delegates.
30 | return handler == _asyncHandler;
31 | }
32 |
33 | public Task InvokeAsync(TEventArgs eventArgs)
34 | {
35 | if (_handler != null)
36 | {
37 | _handler(eventArgs);
38 | return CompletedTask.Instance;
39 | }
40 |
41 | if (_asyncHandler != null)
42 | {
43 | return _asyncHandler(eventArgs);
44 | }
45 |
46 | throw new InvalidOperationException();
47 | }
48 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Internal/AsyncQueueDequeueResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Internal;
6 |
7 | public sealed class AsyncQueueDequeueResult(bool isSuccess, TItem item)
8 | {
9 | public static readonly AsyncQueueDequeueResult NonSuccess = new(false, default);
10 |
11 | public bool IsSuccess { get; } = isSuccess;
12 |
13 | public TItem Item { get; } = item;
14 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Internal/AsyncTaskCompletionSource.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Threading.Tasks;
7 |
8 | namespace MQTTnet.Internal;
9 |
10 | public sealed class AsyncTaskCompletionSource
11 | {
12 | readonly TaskCompletionSource _taskCompletionSource = new(TaskCreationOptions.RunContinuationsAsynchronously);
13 |
14 | public Task Task => _taskCompletionSource.Task;
15 |
16 | public void TrySetCanceled()
17 | {
18 | _taskCompletionSource.TrySetCanceled();
19 | }
20 |
21 | public void TrySetException(Exception exception)
22 | {
23 | _taskCompletionSource.TrySetException(exception);
24 | }
25 |
26 | public bool TrySetResult(TResult result)
27 | {
28 | return _taskCompletionSource.TrySetResult(result);
29 | }
30 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Internal/CancellationTokenSourceExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Threading;
7 |
8 | namespace MQTTnet.Internal;
9 |
10 | public static class CancellationTokenSourceExtensions
11 | {
12 | public static bool TryCancel(this CancellationTokenSource cancellationTokenSource, bool throwOnFirstException = false)
13 | {
14 | if (cancellationTokenSource == null)
15 | {
16 | return false;
17 | }
18 |
19 | try
20 | {
21 | // Checking the _IsCancellationRequested_ here will not throw an
22 | // "ObjectDisposedException" as the getter of the property "Token" will do!
23 | if (cancellationTokenSource.IsCancellationRequested)
24 | {
25 | return false;
26 | }
27 |
28 | cancellationTokenSource.Cancel(throwOnFirstException);
29 | return true;
30 | }
31 | catch (ObjectDisposedException)
32 | {
33 | return false;
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Internal/CompletedTask.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading.Tasks;
6 |
7 | namespace MQTTnet.Internal;
8 |
9 | public static class CompletedTask
10 | {
11 | public static readonly Task Instance = Task.CompletedTask;
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Internal/Disposable.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Internal;
8 |
9 | public abstract class Disposable : IDisposable
10 | {
11 | protected bool IsDisposed { get; private set; }
12 |
13 | protected void ThrowIfDisposed()
14 | {
15 | ObjectDisposedException.ThrowIf(IsDisposed, GetType());
16 | }
17 |
18 | protected virtual void Dispose(bool disposing)
19 | {
20 | }
21 |
22 | // This code added to correctly implement the disposable pattern.
23 | public void Dispose()
24 | {
25 | // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
26 |
27 | if (IsDisposed)
28 | {
29 | return;
30 | }
31 |
32 | IsDisposed = true;
33 |
34 | Dispose(true);
35 | GC.SuppressFinalize(this);
36 | }
37 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Internal/EmptyBuffer.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Buffers;
7 |
8 | namespace MQTTnet.Internal;
9 |
10 | public static class EmptyBuffer
11 | {
12 | public static readonly byte[] Array = [];
13 |
14 | public static readonly ArraySegment ArraySegment = new(Array, 0, 0);
15 |
16 | public static readonly ReadOnlySequence ReadOnlySequence = ReadOnlySequence.Empty;
17 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Internal/MqttClientEvents.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Diagnostics.PacketInspection;
6 |
7 | namespace MQTTnet.Internal;
8 |
9 | public sealed class MqttClientEvents
10 | {
11 | public AsyncEvent ApplicationMessageReceivedEvent { get; } = new();
12 | public AsyncEvent ConnectedEvent { get; } = new();
13 | public AsyncEvent ConnectingEvent { get; } = new();
14 | public AsyncEvent DisconnectedEvent { get; } = new();
15 | public AsyncEvent InspectPacketEvent { get; } = new();
16 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Internal/MqttPacketBusItem.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Threading.Tasks;
7 | using MQTTnet.Packets;
8 |
9 | namespace MQTTnet.Internal;
10 |
11 | public sealed class MqttPacketBusItem
12 | {
13 | readonly AsyncTaskCompletionSource _promise = new();
14 |
15 | public MqttPacketBusItem(MqttPacket packet)
16 | {
17 | Packet = packet ?? throw new ArgumentNullException(nameof(packet));
18 | }
19 |
20 | public event EventHandler Completed;
21 |
22 | public MqttPacket Packet { get; }
23 |
24 | public void Cancel()
25 | {
26 | _promise.TrySetCanceled();
27 | }
28 |
29 | public void Complete()
30 | {
31 | _promise.TrySetResult(Packet);
32 | Completed?.Invoke(this, EventArgs.Empty);
33 | }
34 |
35 | public void Fail(Exception exception)
36 | {
37 | _promise.TrySetException(exception);
38 | }
39 |
40 | public Task WaitAsync()
41 | {
42 | return _promise.Task;
43 | }
44 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Internal/MqttPacketBusPartition.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Internal;
6 |
7 | public enum MqttPacketBusPartition
8 | {
9 | Data,
10 |
11 | Control,
12 |
13 | Health
14 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/LowLevelClient/ILowLevelMqttClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using MQTTnet.Diagnostics.PacketInspection;
5 | using MQTTnet.Packets;
6 |
7 | namespace MQTTnet.LowLevelClient;
8 |
9 | public interface ILowLevelMqttClient : IDisposable
10 | {
11 | event Func InspectPacketAsync;
12 |
13 | bool IsConnected { get; }
14 |
15 | Task ConnectAsync(MqttClientOptions options, CancellationToken cancellationToken = default);
16 |
17 | Task DisconnectAsync(CancellationToken cancellationToken = default);
18 |
19 | Task ReceiveAsync(CancellationToken cancellationToken = default);
20 |
21 | Task SendAsync(MqttPacket packet, CancellationToken cancellationToken = default);
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/MqttApplicationMessageExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Text;
7 |
8 | namespace MQTTnet;
9 |
10 | public static class MqttApplicationMessageExtensions
11 | {
12 | public static string ConvertPayloadToString(this MqttApplicationMessage applicationMessage)
13 | {
14 | ArgumentNullException.ThrowIfNull(applicationMessage);
15 |
16 | if (applicationMessage.Payload.Length == 0)
17 | {
18 | return null;
19 | }
20 |
21 | return Encoding.UTF8.GetString(applicationMessage.Payload);
22 | }
23 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/MqttClientConnectionStatus.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public enum MqttClientConnectionStatus
8 | {
9 | Disconnected,
10 | Disconnecting,
11 | Connected,
12 | Connecting
13 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/MqttPacketIdentifierProvider.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public sealed class MqttPacketIdentifierProvider
8 | {
9 | readonly object _syncRoot = new();
10 |
11 | ushort _value;
12 |
13 | public ushort GetNextPacketIdentifier()
14 | {
15 | lock (_syncRoot)
16 | {
17 | _value++;
18 |
19 | if (_value == 0)
20 | {
21 | // As per official MQTT documentation the package identifier should never be 0.
22 | _value = 1;
23 | }
24 |
25 | return _value;
26 | }
27 | }
28 |
29 | public void Reset()
30 | {
31 | lock (_syncRoot)
32 | {
33 | _value = 0;
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/MqttTopicFilterCompareResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public enum MqttTopicFilterCompareResult
8 | {
9 | NoMatch,
10 |
11 | IsMatch,
12 |
13 | FilterInvalid,
14 |
15 | TopicInvalid
16 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/DefaultMqttCertificatesProvider.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Security.Cryptography.X509Certificates;
7 |
8 | namespace MQTTnet;
9 |
10 | public sealed class DefaultMqttCertificatesProvider : IMqttClientCertificatesProvider
11 | {
12 | readonly X509Certificate2Collection _certificates;
13 |
14 | public DefaultMqttCertificatesProvider(X509Certificate2Collection certificates)
15 | {
16 | _certificates = certificates;
17 | }
18 |
19 | public DefaultMqttCertificatesProvider(IEnumerable certificates)
20 | {
21 | if (certificates != null)
22 | {
23 | _certificates = [];
24 | foreach (var certificate in certificates)
25 | {
26 | _certificates.Add(certificate);
27 | }
28 | }
29 | }
30 |
31 | public X509CertificateCollection GetCertificates()
32 | {
33 | return _certificates;
34 | }
35 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/IMqttClientCertificatesProvider.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Security.Cryptography.X509Certificates;
6 |
7 | namespace MQTTnet;
8 |
9 | public interface IMqttClientCertificatesProvider
10 | {
11 | X509CertificateCollection GetCertificates();
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/IMqttClientChannelOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public interface IMqttClientChannelOptions
8 | {
9 | MqttClientTlsOptions TlsOptions { get; }
10 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/IMqttClientCredentialsProvider.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public interface IMqttClientCredentialsProvider
8 | {
9 | byte[] GetPassword(MqttClientOptions clientOptions);
10 | string GetUserName(MqttClientOptions clientOptions);
11 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/IMqttEnhancedAuthenticationHandler.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading.Tasks;
6 |
7 | namespace MQTTnet;
8 |
9 | public interface IMqttEnhancedAuthenticationHandler
10 | {
11 | Task HandleEnhancedAuthenticationAsync(MqttEnhancedAuthenticationEventArgs eventArgs);
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/MqttClientCertificateSelectionEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Security.Cryptography.X509Certificates;
7 |
8 | namespace MQTTnet;
9 |
10 | public sealed class MqttClientCertificateSelectionEventArgs : EventArgs
11 | {
12 | public MqttClientCertificateSelectionEventArgs(
13 | string targetHost,
14 | X509CertificateCollection localCertificates,
15 | X509Certificate remoteCertificate,
16 | string[] acceptableIssuers,
17 | MqttClientTcpOptions tcpOptions)
18 | {
19 | TargetHost = targetHost;
20 | LocalCertificates = localCertificates;
21 | RemoveCertificate = remoteCertificate;
22 | AcceptableIssuers = acceptableIssuers;
23 | TcpOptions = tcpOptions ?? throw new ArgumentNullException(nameof(tcpOptions));
24 | }
25 |
26 | public string[] AcceptableIssuers { get; }
27 |
28 | public X509CertificateCollection LocalCertificates { get; }
29 |
30 | public X509Certificate RemoveCertificate { get; }
31 |
32 | public string TargetHost { get; }
33 |
34 | public MqttClientTcpOptions TcpOptions { get; }
35 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/MqttClientCertificateValidationEventArgs.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Net.Security;
7 | using System.Security.Cryptography.X509Certificates;
8 |
9 | namespace MQTTnet;
10 |
11 | public sealed class MqttClientCertificateValidationEventArgs : EventArgs
12 | {
13 | public MqttClientCertificateValidationEventArgs(X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors, IMqttClientChannelOptions clientOptions)
14 | {
15 | Certificate = certificate;
16 | Chain = chain;
17 | SslPolicyErrors = sslPolicyErrors;
18 | ClientOptions = clientOptions ?? throw new ArgumentNullException(nameof(clientOptions));
19 | }
20 |
21 | public X509Certificate Certificate { get; }
22 |
23 | public X509Chain Chain { get; }
24 |
25 | public IMqttClientChannelOptions ClientOptions { get; }
26 |
27 | public SslPolicyErrors SslPolicyErrors { get; }
28 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/MqttClientCredentials.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public sealed class MqttClientCredentials : IMqttClientCredentialsProvider
8 | {
9 | readonly byte[] _password;
10 | readonly string _userName;
11 |
12 | public MqttClientCredentials(string userName, byte[] password = null)
13 | {
14 | _userName = userName;
15 | _password = password;
16 | }
17 |
18 | public byte[] GetPassword(MqttClientOptions clientOptions)
19 | {
20 | return _password;
21 | }
22 |
23 | public string GetUserName(MqttClientOptions clientOptions)
24 | {
25 | return _userName;
26 | }
27 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/MqttClientDefaultCertificateValidationHandler.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Linq;
6 | using System.Net.Security;
7 | using System.Security.Cryptography.X509Certificates;
8 |
9 | namespace MQTTnet;
10 |
11 | public sealed class MqttClientDefaultCertificateValidationHandler
12 | {
13 | public static bool Handle(MqttClientCertificateValidationEventArgs eventArgs)
14 | {
15 | if (eventArgs.SslPolicyErrors == SslPolicyErrors.None)
16 | {
17 | return true;
18 | }
19 |
20 | if (eventArgs.Chain.ChainStatus.Any(
21 | c => c.Status is X509ChainStatusFlags.RevocationStatusUnknown or X509ChainStatusFlags.Revoked or X509ChainStatusFlags.OfflineRevocation))
22 | {
23 | if (eventArgs.ClientOptions?.TlsOptions?.IgnoreCertificateRevocationErrors != true)
24 | {
25 | return false;
26 | }
27 | }
28 |
29 | if (eventArgs.Chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.PartialChain))
30 | {
31 | if (eventArgs.ClientOptions?.TlsOptions?.IgnoreCertificateChainErrors != true)
32 | {
33 | return false;
34 | }
35 | }
36 |
37 | return eventArgs.ClientOptions?.TlsOptions?.AllowUntrustedCertificates == true;
38 | }
39 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/MqttClientWebSocketProxyOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public sealed class MqttClientWebSocketProxyOptions
8 | {
9 | public string Address { get; set; }
10 |
11 | public string[] BypassList { get; set; }
12 |
13 | public bool BypassOnLocal { get; set; }
14 |
15 | public string Domain { get; set; }
16 |
17 | public string Password { get; set; }
18 |
19 | public bool UseDefaultCredentials { get; set; }
20 |
21 | public string Username { get; set; }
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/ReceiveMqttEnhancedAuthenticationDataResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MQTTnet.Packets;
7 | using MQTTnet.Protocol;
8 |
9 | namespace MQTTnet;
10 |
11 | public sealed class ReceiveMqttEnhancedAuthenticationDataResult
12 | {
13 | public byte[] AuthenticationData { get; init; }
14 |
15 | public string AuthenticationMethod { get; init; }
16 |
17 | public MqttAuthenticateReasonCode ReasonCode { get; init; }
18 |
19 | public string ReasonString { get; init; }
20 |
21 | public List UserProperties { get; init; }
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Options/SendMqttEnhancedAuthenticationDataOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MQTTnet.Packets;
7 |
8 | namespace MQTTnet;
9 |
10 | public sealed class SendMqttEnhancedAuthenticationDataOptions
11 | {
12 | public byte[] Data { get; init; }
13 |
14 | public string ReasonString { get; init; }
15 |
16 | public List UserProperties { get; init; }
17 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/PacketDispatcher/IMqttPacketAwaitable.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using MQTTnet.Packets;
6 | using System;
7 |
8 | namespace MQTTnet.PacketDispatcher;
9 |
10 | public interface IMqttPacketAwaitable : IDisposable
11 | {
12 | MqttPacketAwaitableFilter Filter { get; }
13 |
14 | void Complete(MqttPacket packet);
15 |
16 | void Fail(Exception exception);
17 |
18 | void Cancel();
19 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/PacketDispatcher/MqttPacketAwaitableFilter.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.PacketDispatcher;
8 |
9 | public sealed class MqttPacketAwaitableFilter
10 | {
11 | public Type Type { get; set; }
12 |
13 | public ushort Identifier { get; set; }
14 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttAuthPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Packets;
9 |
10 | /// Added in MQTTv5.0.0.
11 | public sealed class MqttAuthPacket : MqttPacket
12 | {
13 | public byte[] AuthenticationData { get; set; }
14 |
15 | public string AuthenticationMethod { get; set; }
16 |
17 | public MqttAuthenticateReasonCode ReasonCode { get; set; }
18 |
19 | public string ReasonString { get; set; }
20 |
21 | public List UserProperties { get; set; }
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttDisconnectPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Packets;
9 |
10 | public sealed class MqttDisconnectPacket : MqttPacket
11 | {
12 | ///
13 | /// Added in MQTTv5.
14 | ///
15 | public MqttDisconnectReasonCode ReasonCode { get; set; } = MqttDisconnectReasonCode.NormalDisconnection;
16 |
17 | ///
18 | /// Added in MQTTv5.
19 | ///
20 | public string ReasonString { get; set; }
21 |
22 | ///
23 | /// Added in MQTTv5.
24 | ///
25 | public string ServerReference { get; set; }
26 |
27 | ///
28 | /// Added in MQTTv5.
29 | ///
30 | public uint SessionExpiryInterval { get; set; }
31 |
32 | ///
33 | /// Added in MQTTv5.
34 | ///
35 | public List UserProperties { get; set; }
36 |
37 | public override string ToString()
38 | {
39 | return $"Disconnect: [ReasonCode={ReasonCode}] [ReasonString={ReasonString}] [ServerReference={ServerReference}] [SessionExpiryInterval={SessionExpiryInterval}]";
40 | }
41 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Packets;
6 |
7 | public abstract class MqttPacket;
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttPacketExtensions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Packets;
8 |
9 | public static class MqttPacketExtensions
10 | {
11 | public static string GetRfcName(this MqttPacket packet)
12 | {
13 | ArgumentNullException.ThrowIfNull(packet);
14 |
15 | return packet switch
16 | {
17 | MqttConnectPacket => "CONNECT",
18 | MqttConnAckPacket => "CONNACK",
19 | MqttAuthPacket => "AUTH",
20 | MqttDisconnectPacket => "DISCONNECT",
21 | MqttPingReqPacket => "PINGREQ",
22 | MqttPingRespPacket => "PINGRESP",
23 | MqttSubscribePacket => "SUBSCRIBE",
24 | MqttSubAckPacket => "SUBACK",
25 | MqttUnsubscribePacket => "UNSUBSCRIBE",
26 | MqttUnsubAckPacket => "UNSUBACK",
27 | MqttPublishPacket => "PUBLISH",
28 | MqttPubAckPacket => "PUBACK",
29 | MqttPubRelPacket => "PUBREL",
30 | MqttPubRecPacket => "PUBREC",
31 | MqttPubCompPacket => "PUBCOMP",
32 | _ => packet.GetType().Name
33 | };
34 | }
35 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttPacketWithIdentifier.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Packets;
6 |
7 | public abstract class MqttPacketWithIdentifier : MqttPacket
8 | {
9 | public ushort PacketIdentifier { get; set; }
10 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttPingReqPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Packets;
6 |
7 | public sealed class MqttPingReqPacket : MqttPacket
8 | {
9 | // This is a minor performance improvement.
10 | public static readonly MqttPingReqPacket Instance = new();
11 |
12 | public override string ToString()
13 | {
14 | return "PingReq";
15 | }
16 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttPingRespPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Packets;
6 |
7 | public sealed class MqttPingRespPacket : MqttPacket
8 | {
9 | // This is a minor performance improvement.
10 | public static readonly MqttPingRespPacket Instance = new();
11 |
12 | public override string ToString()
13 | {
14 | return "PingResp";
15 | }
16 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttPubAckPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Packets;
9 |
10 | public sealed class MqttPubAckPacket : MqttPacketWithIdentifier
11 | {
12 | ///
13 | /// Added in MQTTv5.
14 | ///
15 | public MqttPubAckReasonCode ReasonCode { get; set; } = MqttPubAckReasonCode.Success;
16 |
17 | ///
18 | /// Added in MQTTv5.
19 | ///
20 | public string ReasonString { get; set; }
21 |
22 | ///
23 | /// Added in MQTTv5.
24 | ///
25 | public List UserProperties { get; set; }
26 |
27 | public override string ToString()
28 | {
29 | return $"PubAck: [PacketIdentifier={PacketIdentifier}] [ReasonCode={ReasonCode}]";
30 | }
31 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttPubCompPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Packets;
9 |
10 | public sealed class MqttPubCompPacket : MqttPacketWithIdentifier
11 | {
12 | ///
13 | /// Added in MQTTv5.
14 | ///
15 | public MqttPubCompReasonCode ReasonCode { get; set; } = MqttPubCompReasonCode.Success;
16 |
17 | ///
18 | /// Added in MQTTv5.
19 | ///
20 | public string ReasonString { get; set; }
21 |
22 | ///
23 | /// Added in MQTTv5.
24 | ///
25 | public List UserProperties { get; set; }
26 |
27 | public override string ToString()
28 | {
29 | return $"PubComp: [PacketIdentifier={PacketIdentifier}] [ReasonCode={ReasonCode}]";
30 | }
31 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttPubRecPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Packets;
9 |
10 | public sealed class MqttPubRecPacket : MqttPacketWithIdentifier
11 | {
12 | ///
13 | /// Added in MQTTv5.
14 | ///
15 | public MqttPubRecReasonCode ReasonCode { get; set; } = MqttPubRecReasonCode.Success;
16 |
17 | ///
18 | /// Added in MQTTv5.
19 | ///
20 | public string ReasonString { get; set; }
21 |
22 | ///
23 | /// Added in MQTTv5.
24 | ///
25 | public List UserProperties { get; set; }
26 |
27 | public override string ToString()
28 | {
29 | return $"PubRec: [PacketIdentifier={PacketIdentifier}] [ReasonCode={ReasonCode}]";
30 | }
31 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttPubRelPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MQTTnet.Protocol;
7 |
8 | namespace MQTTnet.Packets;
9 |
10 | public sealed class MqttPubRelPacket : MqttPacketWithIdentifier
11 | {
12 | ///
13 | /// Added in MQTTv5.
14 | ///
15 | public MqttPubRelReasonCode ReasonCode { get; set; } = MqttPubRelReasonCode.Success;
16 |
17 | ///
18 | /// Added in MQTTv5.
19 | ///
20 | public string ReasonString { get; set; }
21 |
22 | ///
23 | /// Added in MQTTv5.
24 | ///
25 | public List UserProperties { get; set; }
26 |
27 | public override string ToString()
28 | {
29 | return $"PubRel: [PacketIdentifier={PacketIdentifier}] [ReasonCode={ReasonCode}]";
30 | }
31 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttPublishPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Buffers;
7 | using System.Collections.Generic;
8 | using MQTTnet.Protocol;
9 |
10 | namespace MQTTnet.Packets;
11 |
12 | public sealed class MqttPublishPacket : MqttPacketWithIdentifier
13 | {
14 | public string ContentType { get; set; }
15 |
16 | public byte[] CorrelationData { get; set; }
17 |
18 | public bool Dup { get; set; }
19 |
20 | public uint MessageExpiryInterval { get; set; }
21 |
22 | public MqttPayloadFormatIndicator PayloadFormatIndicator { get; set; } = MqttPayloadFormatIndicator.Unspecified;
23 |
24 | public ArraySegment PayloadSegment { set => Payload = new ReadOnlySequence(value); }
25 |
26 | public ReadOnlySequence Payload { get; set; }
27 |
28 | public MqttQualityOfServiceLevel QualityOfServiceLevel { get; set; } = MqttQualityOfServiceLevel.AtMostOnce;
29 |
30 | public string ResponseTopic { get; set; }
31 |
32 | public bool Retain { get; set; }
33 |
34 | public List SubscriptionIdentifiers { get; set; }
35 |
36 | public string Topic { get; set; }
37 |
38 | public ushort TopicAlias { get; set; }
39 |
40 | public List UserProperties { get; set; }
41 |
42 | public override string ToString()
43 | {
44 | return
45 | $"Publish: [Topic={Topic}] [PayloadLength={Payload.Length}] [QoSLevel={QualityOfServiceLevel}] [Dup={Dup}] [Retain={Retain}] [PacketIdentifier={PacketIdentifier}]";
46 | }
47 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttSubAckPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using MQTTnet.Protocol;
8 |
9 | namespace MQTTnet.Packets;
10 |
11 | public sealed class MqttSubAckPacket : MqttPacketWithIdentifier
12 | {
13 | ///
14 | /// Reason Code is used in MQTTv5.0.0 and backward compatible to v.3.1.1. Return Code is used in MQTTv3.1.1
15 | ///
16 | public List ReasonCodes { get; set; }
17 |
18 | ///
19 | /// Added in MQTTv5.
20 | ///
21 | public string ReasonString { get; set; }
22 |
23 | ///
24 | /// Added in MQTTv5.
25 | ///
26 | public List UserProperties { get; set; }
27 |
28 | public override string ToString()
29 | {
30 | var reasonCodesText = string.Join(",", ReasonCodes.Select(f => f.ToString()));
31 |
32 | return $"SubAck: [PacketIdentifier={PacketIdentifier}] [ReasonCode={reasonCodesText}]";
33 | }
34 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttSubscribePacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Linq;
7 |
8 | namespace MQTTnet.Packets;
9 |
10 | public sealed class MqttSubscribePacket : MqttPacketWithIdentifier
11 | {
12 | ///
13 | /// It is a Protocol Error if the Subscription Identifier has a value of 0.
14 | ///
15 | public uint SubscriptionIdentifier { get; set; }
16 |
17 | public List TopicFilters { get; set; } = [];
18 |
19 | ///
20 | /// Added in MQTTv5.
21 | ///
22 | public List UserProperties { get; set; }
23 |
24 | public override string ToString()
25 | {
26 | var topicFiltersText = string.Join(",", TopicFilters.Select(f => f.Topic + "@" + f.QualityOfServiceLevel));
27 | return $"Subscribe: [PacketIdentifier={PacketIdentifier}] [TopicFilters={topicFiltersText}]";
28 | }
29 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttUnsubAckPacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using MQTTnet.Protocol;
8 |
9 | namespace MQTTnet.Packets;
10 |
11 | public sealed class MqttUnsubAckPacket : MqttPacketWithIdentifier
12 | {
13 | ///
14 | /// Added in MQTTv5.
15 | ///
16 | public List ReasonCodes { get; set; }
17 |
18 | ///
19 | /// Added in MQTTv5.
20 | ///
21 | public string ReasonString { get; set; }
22 |
23 | ///
24 | /// Added in MQTTv5.
25 | ///
26 | public List UserProperties { get; set; }
27 |
28 | public override string ToString()
29 | {
30 | var reasonCodesText = string.Empty;
31 | if (ReasonCodes != null)
32 | {
33 | reasonCodesText = string.Join(",", ReasonCodes?.Select(f => f.ToString()));
34 | }
35 |
36 | return $"UnsubAck: [PacketIdentifier={PacketIdentifier}] [ReasonCodes={reasonCodesText}] [ReasonString={ReasonString}]";
37 | }
38 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttUnsubscribePacket.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 |
7 | namespace MQTTnet.Packets;
8 |
9 | public sealed class MqttUnsubscribePacket : MqttPacketWithIdentifier
10 | {
11 | public List TopicFilters { get; set; } = [];
12 |
13 | ///
14 | /// Added in MQTTv5.
15 | ///
16 | public List UserProperties { get; set; }
17 |
18 | public override string ToString()
19 | {
20 | var topicFiltersText = string.Join(",", TopicFilters);
21 | return $"Unsubscribe: [PacketIdentifier={PacketIdentifier}] [TopicFilters={topicFiltersText}]";
22 | }
23 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Packets/MqttUserProperty.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet.Packets;
8 |
9 | public sealed class MqttUserProperty
10 | {
11 | public MqttUserProperty(string name, string value)
12 | {
13 | Name = name ?? throw new ArgumentNullException(nameof(name));
14 | Value = value ?? throw new ArgumentNullException(nameof(value));
15 | }
16 |
17 | public string Name { get; }
18 |
19 | public string Value { get; }
20 |
21 | public override bool Equals(object obj)
22 | {
23 | return Equals(obj as MqttUserProperty);
24 | }
25 |
26 | public bool Equals(MqttUserProperty other)
27 | {
28 | if (other == null)
29 | {
30 | return false;
31 | }
32 |
33 | if (ReferenceEquals(other, this))
34 | {
35 | return true;
36 | }
37 |
38 | return string.Equals(Name, other.Name, StringComparison.Ordinal) && string.Equals(Value, other.Value, StringComparison.Ordinal);
39 | }
40 |
41 | public override int GetHashCode()
42 | {
43 | return Name.GetHashCode() ^ Value.GetHashCode();
44 | }
45 |
46 | public override string ToString()
47 | {
48 | return $"{Name} = {Value}";
49 | }
50 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 |
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttAuthenticateReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttAuthenticateReasonCode
8 | {
9 | Success = 0,
10 | ContinueAuthentication = 24,
11 | ReAuthenticate = 25
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttConnectReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttConnectReasonCode
8 | {
9 | Success = 0,
10 | UnspecifiedError = 128,
11 | MalformedPacket = 129,
12 | ProtocolError = 130,
13 | ImplementationSpecificError = 131,
14 | UnsupportedProtocolVersion = 132,
15 | ClientIdentifierNotValid = 133,
16 | BadUserNameOrPassword = 134,
17 | NotAuthorized = 135,
18 | ServerUnavailable = 136,
19 | ServerBusy = 137,
20 | Banned = 138,
21 | BadAuthenticationMethod = 140,
22 | TopicNameInvalid = 144,
23 | PacketTooLarge = 149,
24 | QuotaExceeded = 151,
25 | PayloadFormatInvalid = 153,
26 | RetainNotSupported = 154,
27 | QoSNotSupported = 155,
28 | UseAnotherServer = 156,
29 | ServerMoved = 157,
30 | ConnectionRateExceeded = 159
31 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttConnectReturnCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttConnectReturnCode
8 | {
9 | ConnectionAccepted = 0x00,
10 | ConnectionRefusedUnacceptableProtocolVersion = 0x01,
11 | ConnectionRefusedIdentifierRejected = 0x02,
12 | ConnectionRefusedServerUnavailable = 0x03,
13 | ConnectionRefusedBadUsernameOrPassword = 0x04,
14 | ConnectionRefusedNotAuthorized = 0x05
15 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttControlPacketType.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttControlPacketType
8 | {
9 | Connect = 1,
10 | ConnAck = 2,
11 | Publish = 3,
12 | PubAck = 4,
13 | PubRec = 5,
14 | PubRel = 6,
15 | PubComp = 7,
16 | Subscribe = 8,
17 | SubAck = 9,
18 | Unsubscribe = 10,
19 | UnsubAck = 11,
20 | PingReq = 12,
21 | PingResp = 13,
22 | Disconnect = 14,
23 | Auth = 15
24 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttDisconnectReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttDisconnectReasonCode
8 | {
9 | NormalDisconnection = 0,
10 | DisconnectWithWillMessage = 4,
11 | UnspecifiedError = 128,
12 | MalformedPacket = 129,
13 | ProtocolError = 130,
14 | ImplementationSpecificError = 131,
15 | NotAuthorized = 135,
16 | ServerBusy = 137,
17 | ServerShuttingDown = 139,
18 | KeepAliveTimeout = 141,
19 | SessionTakenOver = 142,
20 | TopicFilterInvalid = 143,
21 | TopicNameInvalid = 144,
22 | ReceiveMaximumExceeded = 147,
23 | TopicAliasInvalid = 148,
24 | PacketTooLarge = 149,
25 | MessageRateTooHigh = 150,
26 | QuotaExceeded = 151,
27 | AdministrativeAction = 152,
28 | PayloadFormatInvalid = 153,
29 | RetainNotSupported = 154,
30 | QoSNotSupported = 155,
31 | UseAnotherServer = 156,
32 | ServerMoved = 157,
33 | SharedSubscriptionsNotSupported = 158,
34 | ConnectionRateExceeded = 159,
35 | MaximumConnectTime = 160,
36 | SubscriptionIdentifiersNotSupported = 161,
37 | WildcardSubscriptionsNotSupported = 162
38 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttPayloadFormatIndicator.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttPayloadFormatIndicator
8 | {
9 | Unspecified = 0,
10 | CharacterData = 1
11 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttPorts.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public static class MqttPorts
8 | {
9 | public const int Default = 1883;
10 |
11 | public const int Secure = 8883;
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttPropertyId.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttPropertyId
8 | {
9 | None = 0,
10 |
11 | PayloadFormatIndicator = 1,
12 | MessageExpiryInterval = 2,
13 | ContentType = 3,
14 | ResponseTopic = 8,
15 | CorrelationData = 9,
16 | SubscriptionIdentifier = 11,
17 | SessionExpiryInterval = 17,
18 | AssignedClientIdentifier = 18,
19 | ServerKeepAlive = 19,
20 | AuthenticationMethod = 21,
21 | AuthenticationData = 22,
22 | RequestProblemInformation = 23,
23 | WillDelayInterval = 24,
24 | RequestResponseInformation = 25,
25 | ResponseInformation = 26,
26 | ServerReference = 28,
27 | ReasonString = 31,
28 | ReceiveMaximum = 33,
29 | TopicAliasMaximum = 34,
30 | TopicAlias = 35,
31 | MaximumQoS = 36,
32 | RetainAvailable = 37,
33 | UserProperty = 38,
34 | MaximumPacketSize = 39,
35 | WildcardSubscriptionAvailable = 40,
36 | SubscriptionIdentifiersAvailable = 41,
37 | SharedSubscriptionAvailable = 42
38 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttPubAckReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttPubAckReasonCode
8 | {
9 | Success = 0,
10 |
11 | ///
12 | /// The message is accepted but there are no subscribers. This is sent only by the Server. If the Server knows that there are no matching subscribers, it MAY use this Reason Code instead of 0x00 (Success).
13 | ///
14 | NoMatchingSubscribers = 16,
15 |
16 | UnspecifiedError = 128,
17 | ImplementationSpecificError = 131,
18 | NotAuthorized = 135,
19 | TopicNameInvalid = 144,
20 | PacketIdentifierInUse = 145,
21 | QuotaExceeded = 151,
22 | PayloadFormatInvalid = 153
23 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttPubCompReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttPubCompReasonCode
8 | {
9 | Success = 0,
10 | PacketIdentifierNotFound = 146
11 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttPubRecReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttPubRecReasonCode
8 | {
9 | Success = 0,
10 | NoMatchingSubscribers = 16,
11 | UnspecifiedError = 128,
12 | ImplementationSpecificError = 131,
13 | NotAuthorized = 135,
14 | TopicNameInvalid = 144,
15 | PacketIdentifierInUse = 145,
16 | QuotaExceeded = 151,
17 | PayloadFormatInvalid = 153
18 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttPubRelReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttPubRelReasonCode
8 | {
9 | Success = 0,
10 | PacketIdentifierNotFound = 146
11 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttQualityOfServiceLevel.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttQualityOfServiceLevel
8 | {
9 | AtMostOnce = 0x00,
10 | AtLeastOnce = 0x01,
11 | ExactlyOnce = 0x02
12 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttRetainHandling.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttRetainHandling
8 | {
9 | SendAtSubscribe = 0,
10 |
11 | SendAtSubscribeIfNewSubscriptionOnly = 1,
12 |
13 | DoNotSendOnSubscribe = 2
14 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttSubscribeReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttSubscribeReasonCode
8 | {
9 | // Compatible with MQTTv3.1.1.
10 | GrantedQoS0 = 0x00,
11 | GrantedQoS1 = 0x01,
12 | GrantedQoS2 = 0x02,
13 | UnspecifiedError = 0x80,
14 |
15 | // New in MQTTv5.
16 | ImplementationSpecificError = 131,
17 | NotAuthorized = 135,
18 | TopicFilterInvalid = 143,
19 | PacketIdentifierInUse = 145,
20 | QuotaExceeded = 151,
21 | SharedSubscriptionsNotSupported = 158,
22 | SubscriptionIdentifiersNotSupported = 161,
23 | WildcardSubscriptionsNotSupported = 162
24 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttSubscribeReturnCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttSubscribeReturnCode
8 | {
9 | SuccessMaximumQoS0 = 0x00,
10 | SuccessMaximumQoS1 = 0x01,
11 | SuccessMaximumQoS2 = 0x02,
12 | Failure = 0x80
13 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Protocol/MqttUnsubscribeReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet.Protocol;
6 |
7 | public enum MqttUnsubscribeReasonCode
8 | {
9 | Success = 0,
10 | NoSubscriptionExisted = 17,
11 | UnspecifiedError = 128,
12 | ImplementationSpecificError = 131,
13 | NotAuthorized = 135,
14 | TopicFilterInvalid = 143,
15 | PacketIdentifierInUse = 145
16 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Publishing/MqttClientPublishReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public enum MqttClientPublishReasonCode
8 | {
9 | Success = 0,
10 |
11 | NoMatchingSubscribers = 16,
12 | UnspecifiedError = 128,
13 | ImplementationSpecificError = 131,
14 | NotAuthorized = 135,
15 | TopicNameInvalid = 144,
16 | PacketIdentifierInUse = 145,
17 | QuotaExceeded = 151,
18 | PayloadFormatInvalid = 153
19 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Receiving/MqttApplicationMessageReceivedReasonCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public enum MqttApplicationMessageReceivedReasonCode
8 | {
9 | Success = 0,
10 | NoMatchingSubscribers = 16,
11 | UnspecifiedError = 128,
12 | ImplementationSpecificError = 131,
13 | NotAuthorized = 135,
14 | TopicNameInvalid = 144,
15 | PacketIdentifierInUse = 145,
16 | PacketIdentifierNotFound = 146,
17 | QuotaExceeded = 151,
18 | PayloadFormatInvalid = 153
19 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Subscribing/MqttClientSubscribeResultCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public enum MqttClientSubscribeResultCode
8 | {
9 | GrantedQoS0 = 0x00,
10 | GrantedQoS1 = 0x01,
11 | GrantedQoS2 = 0x02,
12 | UnspecifiedError = 0x80,
13 |
14 | ImplementationSpecificError = 131,
15 | NotAuthorized = 135,
16 | TopicFilterInvalid = 143,
17 | PacketIdentifierInUse = 145,
18 | QuotaExceeded = 151,
19 | SharedSubscriptionsNotSupported = 158,
20 | SubscriptionIdentifiersNotSupported = 161,
21 | WildcardSubscriptionsNotSupported = 162
22 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Subscribing/MqttClientSubscribeResultItem.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Packets;
7 |
8 | namespace MQTTnet;
9 |
10 | public sealed class MqttClientSubscribeResultItem
11 | {
12 | public MqttClientSubscribeResultItem(MqttTopicFilter topicFilter, MqttClientSubscribeResultCode resultCode)
13 | {
14 | TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
15 | ResultCode = resultCode;
16 | }
17 |
18 | ///
19 | /// Gets or sets the result code.
20 | /// MQTT 5.0.0+ feature.
21 | ///
22 | public MqttClientSubscribeResultCode ResultCode { get; }
23 |
24 | ///
25 | /// Gets or sets the topic filter.
26 | /// The topic filter can contain topics and wildcards.
27 | ///
28 | public MqttTopicFilter TopicFilter { get; }
29 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Unsubscribing/MqttClientUnsubscribeOptions.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MQTTnet.Packets;
7 |
8 | namespace MQTTnet;
9 |
10 | public sealed class MqttClientUnsubscribeOptions
11 | {
12 | ///
13 | /// Gets or sets a list of topic filters the client wants to unsubscribe from.
14 | /// Topic filters can include regular topics or wild cards.
15 | ///
16 | public List TopicFilters { get; set; } = [];
17 |
18 | ///
19 | /// Gets or sets the user properties.
20 | /// In MQTT 5, user properties are basic UTF-8 string key-value pairs that you can append to almost every type of MQTT
21 | /// packet.
22 | /// As long as you don’t exceed the maximum message size, you can use an unlimited number of user properties to add
23 | /// metadata to MQTT messages and pass information between publisher, broker, and subscriber.
24 | /// The feature is very similar to the HTTP header concept.
25 | /// MQTT 5.0.0+ feature.
26 | ///
27 | public List UserProperties { get; set; }
28 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Unsubscribing/MqttClientUnsubscribeOptionsValidator.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using MQTTnet.Formatter;
7 |
8 | namespace MQTTnet;
9 |
10 | public static class MqttClientUnsubscribeOptionsValidator
11 | {
12 | public static void ThrowIfNotSupported(MqttClientUnsubscribeOptions options, MqttProtocolVersion protocolVersion)
13 | {
14 | ArgumentNullException.ThrowIfNull(options);
15 |
16 | if (protocolVersion == MqttProtocolVersion.V500)
17 | {
18 | // Everything is supported.
19 | return;
20 | }
21 |
22 | if (options.UserProperties?.Count > 0)
23 | {
24 | Throw(nameof(options.UserProperties));
25 | }
26 | }
27 |
28 | static void Throw(string featureName)
29 | {
30 | throw new NotSupportedException($"Feature {featureName} requires MQTT version 5.0.0.");
31 | }
32 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Unsubscribing/MqttClientUnsubscribeResultCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace MQTTnet;
6 |
7 | public enum MqttClientUnsubscribeResultCode
8 | {
9 | Success = 0,
10 | NoSubscriptionExisted = 17,
11 | UnspecifiedError = 128,
12 | ImplementationSpecificError = 131,
13 | NotAuthorized = 135,
14 | TopicFilterInvalid = 143,
15 | PacketIdentifierInUse = 145
16 | }
--------------------------------------------------------------------------------
/Source/MQTTnet/Unsubscribing/MqttClientUnsubscribeResultItem.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace MQTTnet;
8 |
9 | public sealed class MqttClientUnsubscribeResultItem
10 | {
11 | public MqttClientUnsubscribeResultItem(string topicFilter, MqttClientUnsubscribeResultCode resultCode)
12 | {
13 | TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
14 | ResultCode = resultCode;
15 | }
16 |
17 | ///
18 | /// Gets or sets the result code.
19 | /// MQTT 5.0.0+ feature.
20 | ///
21 | public MqttClientUnsubscribeResultCode ResultCode { get; }
22 |
23 | ///
24 | /// Gets or sets the topic filter.
25 | /// The topic filter can contain topics and wildcards.
26 | ///
27 | public string TopicFilter { get; }
28 | }
--------------------------------------------------------------------------------
/Source/ReleaseNotes.md:
--------------------------------------------------------------------------------
1 | * Core: Used new language features across the entire library
2 | * Core: Performance improvements
3 |
--------------------------------------------------------------------------------