diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec
index eded1fd..6aafdc6 100644
--- a/Build/MQTTnet.nuspec
+++ b/Build/MQTTnet.nuspec
@@ -11,9 +11,16 @@
false
MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker) and supports v3.1.0, v3.1.1 and v5.0.0 of the MQTT protocol.
-* [Core] Removed dedicated UWP builds. The lib is now supporting net452, netstandard1.3 and netstandard2.0 only (which covers mostly everything currently supported by MS).
-* [Server] Refactoring of TLS certificate handling (BREAKING CHANGE!)
-* [MQTTnet.Server] Added support for passwords when using TLS certificate (BREAKING CHANGE!)
+* [Core] Nuget packages with symbols are now also published to improve debugging.
+* [Core] Improve task handling (thanks to @mwinterb)
+* [ManagedClient] Fix a race condition in the message storage (thanks to @PaulFake).
+* [Server] Added items dictionary to client session in order to share data across interceptors as along as the session exists.
+* [Server] Exposed CONNECT packet properties in Application Message and Subscription interceptor.
+* [Server] Fixed: Sending Large packets with AspnetCore based connection throws System.ArgumentException.
+* [Server] Fixed wrong usage of socket option _NoDelay_.
+* [Server] Added remote certificate validation callback (thanks to @rudacs).
+* [Server] Add support for certificate passwords (thanks to @cslutgen).
+* [MQTTnet.Server] Added REST API for publishing basic messages.
Copyright Christian Kratky 2016-2019
MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin
@@ -30,22 +37,31 @@
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Build/build.ps1 b/Build/build.ps1
index 08107dc..33f2767 100644
--- a/Build/build.ps1
+++ b/Build/build.ps1
@@ -14,26 +14,34 @@ Write-Host
# Build the core library
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
+&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
+&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
# Build the ASP.NET Core 2.0 extension
&$msbuild ..\Source\MQTTnet.AspNetCore\MQTTnet.AspNetCore.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
# Build the RPC extension
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
+&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
+&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
# Build the Managed Client extension
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
+&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
+&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
# Build the WebSocket4Net extension
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
+&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
+&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
# Create NuGet packages.
diff --git a/MQTTnet.noUWP.sln b/MQTTnet.noUWP.sln
new file mode 100644
index 0000000..3d842a5
--- /dev/null
+++ b/MQTTnet.noUWP.sln
@@ -0,0 +1,260 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27004.2010
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{9248C2E1-B9D6-40BF-81EC-86004D7765B4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{32A630A7-2598-41D7-B625-204CD906F5FB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet", "Source\MQTTnet\MQTTnet.csproj", "{3587E506-55A2-4EB3-99C7-DC01E42D25D2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{67C28AC1-BC3A-420A-BE9C-FA2401431CF9}"
+ ProjectSection(SolutionItems) = preProject
+ Build\build.ps1 = Build\build.ps1
+ Build\MQTTnet.AspNetCore.nuspec = Build\MQTTnet.AspNetCore.nuspec
+ Build\MQTTnet.Extensions.ManagedClient.nuspec = Build\MQTTnet.Extensions.ManagedClient.nuspec
+ Build\MQTTnet.Extensions.Rpc.nuspec = Build\MQTTnet.Extensions.Rpc.nuspec
+ Build\MQTTnet.nuspec = Build\MQTTnet.nuspec
+ Build\upload.ps1 = Build\upload.ps1
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B3F60ECB-45BA-4C66-8903-8BB89CA67998}"
+ ProjectSection(SolutionItems) = preProject
+ .bettercodehub.yml = .bettercodehub.yml
+ appveyor.yml = appveyor.yml
+ LICENSE = LICENSE
+ README.md = README.md
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.NetCore", "Tests\MQTTnet.TestApp.NetCore\MQTTnet.TestApp.NetCore.csproj", "{3D283AAD-AAA8-4339-8394-52F80B6304DB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.AspNetCore2", "Tests\MQTTnet.TestApp.AspNetCore2\MQTTnet.TestApp.AspNetCore2.csproj", "{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore", "Source\MQTTnet.AspnetCore\MQTTnet.AspNetCore.csproj", "{F10C4060-F7EE-4A83-919F-FF723E72F94A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{12816BCC-AF9E-44A9-9AE5-C246AF2A0587}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.Rpc", "Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj", "{C444E9C8-95FA-430E-9126-274129DE16CD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Benchmarks", "Tests\MQTTnet.Benchmarks\MQTTnet.Benchmarks.csproj", "{998D04DD-7CB0-45F5-A393-E2495C16399E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.ManagedClient", "Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj", "{C400533A-8EBA-4F0B-BF4D-295C3708604B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore.Tests", "Tests\MQTTnet.AspNetCore.Tests\MQTTnet.AspNetCore.Tests.csproj", "{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Tests", "Tests\MQTTnet.Core.Tests\MQTTnet.Tests.csproj", "{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Server", "Source\MQTTnet.Server\MQTTnet.Server.csproj", "{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.WebSocket4Net", "Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj", "{9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|ARM.Build.0 = Debug|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x64.Build.0 = Debug|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x86.Build.0 = Debug|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|ARM.ActiveCfg = Release|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|ARM.Build.0 = Release|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x64.ActiveCfg = Release|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x64.Build.0 = Release|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x86.ActiveCfg = Release|Any CPU
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x86.Build.0 = Release|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|ARM.Build.0 = Debug|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x64.Build.0 = Debug|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x86.Build.0 = Debug|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|ARM.ActiveCfg = Release|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|ARM.Build.0 = Release|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x64.ActiveCfg = Release|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x64.Build.0 = Release|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x86.ActiveCfg = Release|Any CPU
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x86.Build.0 = Release|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|ARM.Build.0 = Debug|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x64.Build.0 = Debug|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x86.Build.0 = Debug|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|ARM.ActiveCfg = Release|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|ARM.Build.0 = Release|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x64.ActiveCfg = Release|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x64.Build.0 = Release|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x86.ActiveCfg = Release|Any CPU
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x86.Build.0 = Release|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|ARM.Build.0 = Debug|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x64.Build.0 = Debug|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x86.Build.0 = Debug|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|ARM.ActiveCfg = Release|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|ARM.Build.0 = Release|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x64.ActiveCfg = Release|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x64.Build.0 = Release|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x86.ActiveCfg = Release|Any CPU
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x86.Build.0 = Release|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|ARM.Build.0 = Debug|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x64.Build.0 = Debug|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x86.Build.0 = Debug|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|ARM.ActiveCfg = Release|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|ARM.Build.0 = Release|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x64.ActiveCfg = Release|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x64.Build.0 = Release|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x86.ActiveCfg = Release|Any CPU
+ {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x86.Build.0 = Release|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|ARM.Build.0 = Debug|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x64.Build.0 = Debug|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x86.Build.0 = Debug|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|ARM.ActiveCfg = Release|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|ARM.Build.0 = Release|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x64.ActiveCfg = Release|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x64.Build.0 = Release|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x86.ActiveCfg = Release|Any CPU
+ {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x86.Build.0 = Release|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|ARM.Build.0 = Debug|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x64.Build.0 = Debug|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x86.Build.0 = Debug|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|ARM.ActiveCfg = Release|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|ARM.Build.0 = Release|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x64.ActiveCfg = Release|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x64.Build.0 = Release|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x86.ActiveCfg = Release|Any CPU
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x86.Build.0 = Release|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|ARM.Build.0 = Debug|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x64.Build.0 = Debug|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x86.Build.0 = Debug|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|ARM.ActiveCfg = Release|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|ARM.Build.0 = Release|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x64.ActiveCfg = Release|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x64.Build.0 = Release|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x86.ActiveCfg = Release|Any CPU
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x86.Build.0 = Release|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|ARM.Build.0 = Debug|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x64.Build.0 = Debug|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x86.Build.0 = Debug|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|ARM.ActiveCfg = Release|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|ARM.Build.0 = Release|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x64.ActiveCfg = Release|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x64.Build.0 = Release|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x86.ActiveCfg = Release|Any CPU
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x86.Build.0 = Release|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|ARM.Build.0 = Debug|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x64.Build.0 = Debug|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x86.Build.0 = Debug|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|ARM.ActiveCfg = Release|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|ARM.Build.0 = Release|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x64.ActiveCfg = Release|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x64.Build.0 = Release|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x86.ActiveCfg = Release|Any CPU
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x86.Build.0 = Release|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|ARM.Build.0 = Debug|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x64.Build.0 = Debug|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x86.Build.0 = Debug|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|ARM.ActiveCfg = Release|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|ARM.Build.0 = Release|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x64.ActiveCfg = Release|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x64.Build.0 = Release|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x86.ActiveCfg = Release|Any CPU
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {3587E506-55A2-4EB3-99C7-DC01E42D25D2} = {32A630A7-2598-41D7-B625-204CD906F5FB}
+ {3D283AAD-AAA8-4339-8394-52F80B6304DB} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
+ {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
+ {F10C4060-F7EE-4A83-919F-FF723E72F94A} = {32A630A7-2598-41D7-B625-204CD906F5FB}
+ {C444E9C8-95FA-430E-9126-274129DE16CD} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587}
+ {998D04DD-7CB0-45F5-A393-E2495C16399E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
+ {C400533A-8EBA-4F0B-BF4D-295C3708604B} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587}
+ {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
+ {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
+ {DADEA836-5CC3-474C-A2D8-4D0F31118CD7} = {32A630A7-2598-41D7-B625-204CD906F5FB}
+ {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {07536672-5CBC-4BE3-ACE0-708A431A7894}
+ EndGlobalSection
+EndGlobal
diff --git a/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj b/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj
index 80131c4..b59b7f4 100644
--- a/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj
+++ b/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj
@@ -2,13 +2,27 @@
netstandard1.3;netstandard2.0
- $(TargetFrameworks);net452
+ $(TargetFrameworks);net452;net461
+ $(TargetFrameworks);uap10.0
+
+ false
+ UAP,Version=v10.0
+ UAP
+ 10.0.17134.0
+ 10.0.10240.0
+ .NETCore
+ v5.0
+ $(DefineConstants);WINDOWS_UWP
+ en
+ $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets
+
+
diff --git a/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj b/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj
index 80131c4..b59b7f4 100644
--- a/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj
+++ b/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj
@@ -2,13 +2,27 @@
netstandard1.3;netstandard2.0
- $(TargetFrameworks);net452
+ $(TargetFrameworks);net452;net461
+ $(TargetFrameworks);uap10.0
+
+ false
+ UAP,Version=v10.0
+ UAP
+ 10.0.17134.0
+ 10.0.10240.0
+ .NETCore
+ v5.0
+ $(DefineConstants);WINDOWS_UWP
+ en
+ $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets
+
+
diff --git a/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj b/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj
index 639e048..bdf26c6 100644
--- a/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj
+++ b/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj
@@ -2,13 +2,27 @@
netstandard1.3;netstandard2.0
- $(TargetFrameworks);net452
+ $(TargetFrameworks);net452;net461
+ $(TargetFrameworks);uap10.0
+
+ false
+ UAP,Version=v10.0
+ UAP
+ 10.0.17134.0
+ 10.0.10240.0
+ .NETCore
+ v5.0
+ $(DefineConstants);WINDOWS_UWP
+ en
+ $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets
+
+
diff --git a/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs b/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs
index fec0809..efbf08b 100644
--- a/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs
+++ b/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs
@@ -8,10 +8,16 @@
{
#if NET452
return "net452";
+#elif NET461
+ return "net461";
+#elif NET472
+ return "net472";
#elif NETSTANDARD1_3
return "netstandard1.3";
#elif NETSTANDARD2_0
return "netstandard2.0";
+#elif WINDOWS_UWP
+ return "uap10.0";
#endif
}
}
diff --git a/Source/MQTTnet/Formatter/MqttPacketReader.cs b/Source/MQTTnet/Formatter/MqttPacketReader.cs
index 5cd4dcf..2589c5b 100644
--- a/Source/MQTTnet/Formatter/MqttPacketReader.cs
+++ b/Source/MQTTnet/Formatter/MqttPacketReader.cs
@@ -55,7 +55,16 @@ namespace MQTTnet.Formatter
};
}
+#if WINDOWS_UWP
+ // UWP will have a dead lock when calling this not async.
var bodyLength = await ReadBodyLengthAsync(buffer[1], cancellationToken).ConfigureAwait(false);
+#else
+ // Here the async/await pattern is not used because the overhead of context switches
+ // is too big for reading 1 byte in a row. We expect that the remaining data was sent
+ // directly after the initial bytes. If the client disconnects just in this moment we
+ // will get an exception anyway.
+ var bodyLength = ReadBodyLength(buffer[1], cancellationToken);
+#endif
if (!bodyLength.HasValue)
{
@@ -72,6 +81,49 @@ namespace MQTTnet.Formatter
};
}
+#if !WINDOWS_UWP
+ private int? ReadBodyLength(byte initialEncodedByte, CancellationToken cancellationToken)
+ {
+ var offset = 0;
+ var multiplier = 128;
+ var value = initialEncodedByte & 127;
+ int encodedByte = initialEncodedByte;
+
+ while ((encodedByte & 128) != 0)
+ {
+ offset++;
+ if (offset > 3)
+ {
+ throw new MqttProtocolViolationException("Remaining length is invalid.");
+ }
+
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return null;
+ }
+
+ var readCount = _channel.ReadAsync(_singleByteBuffer, 0, 1, cancellationToken).GetAwaiter().GetResult();
+
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return null;
+ }
+
+ if (readCount == 0)
+ {
+ return null;
+ }
+
+ encodedByte = _singleByteBuffer[0];
+
+ value += (encodedByte & 127) * multiplier;
+ multiplier *= 128;
+ }
+
+ return value;
+ }
+#else
+
private async Task ReadBodyLengthAsync(byte initialEncodedByte, CancellationToken cancellationToken)
{
var offset = 0;
@@ -112,5 +164,6 @@ namespace MQTTnet.Formatter
return value;
}
+#endif
}
}
diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs
new file mode 100644
index 0000000..cb0f71c
--- /dev/null
+++ b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs
@@ -0,0 +1,196 @@
+#if WINDOWS_UWP
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using Windows.Networking;
+using Windows.Networking.Sockets;
+using Windows.Security.Cryptography.Certificates;
+using MQTTnet.Channel;
+using MQTTnet.Client.Options;
+using MQTTnet.Server;
+
+namespace MQTTnet.Implementations
+{
+ public class MqttTcpChannel : IMqttChannel
+ {
+ private readonly MqttClientTcpOptions _options;
+ private readonly int _bufferSize;
+
+ private StreamSocket _socket;
+ private Stream _readStream;
+ private Stream _writeStream;
+
+ public MqttTcpChannel(IMqttClientOptions clientOptions)
+ {
+ _options = (MqttClientTcpOptions)clientOptions.ChannelOptions;
+ _bufferSize = _options.BufferSize;
+ }
+
+ public MqttTcpChannel(StreamSocket socket, X509Certificate2 clientCertificate, IMqttServerOptions serverOptions)
+ {
+ _socket = socket ?? throw new ArgumentNullException(nameof(socket));
+ _bufferSize = serverOptions.DefaultEndpointOptions.BufferSize;
+
+ CreateStreams();
+
+ IsSecureConnection = socket.Information.ProtectionLevel >= SocketProtectionLevel.Tls12;
+ ClientCertificate = clientCertificate;
+
+ Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort;
+ }
+
+ public static Func> CustomIgnorableServerCertificateErrorsResolver { get; set; }
+
+ public string Endpoint { get; private set; }
+
+ public bool IsSecureConnection { get; }
+
+ public X509Certificate2 ClientCertificate { get; }
+
+ public async Task ConnectAsync(CancellationToken cancellationToken)
+ {
+ if (_socket == null)
+ {
+ _socket = new StreamSocket();
+ _socket.Control.NoDelay = _options.NoDelay;
+ _socket.Control.KeepAlive = true;
+ }
+
+ if (_options.TlsOptions?.UseTls != true)
+ {
+ await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString());
+ }
+ else
+ {
+ _socket.Control.ClientCertificate = LoadCertificate(_options);
+
+ foreach (var ignorableChainValidationResult in ResolveIgnorableServerCertificateErrors())
+ {
+ _socket.Control.IgnorableServerCertificateErrors.Add(ignorableChainValidationResult);
+ }
+
+ var socketProtectionLevel = SocketProtectionLevel.Tls12;
+ if (_options.TlsOptions.SslProtocol == SslProtocols.Tls11)
+ {
+ socketProtectionLevel = SocketProtectionLevel.Tls11;
+ }
+ else if (_options.TlsOptions.SslProtocol == SslProtocols.Tls)
+ {
+ socketProtectionLevel = SocketProtectionLevel.Tls10;
+ }
+
+ await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString(), socketProtectionLevel);
+ }
+
+ Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort;
+
+ CreateStreams();
+ }
+
+ public Task DisconnectAsync(CancellationToken cancellationToken)
+ {
+ Dispose();
+ return Task.FromResult(0);
+ }
+
+ public Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ return _readStream.ReadAsync(buffer, offset, count, cancellationToken);
+ }
+
+ public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ // In the write method only the internal buffer will be filled. So here is no
+ // async/await required. The real network transmit is done when calling the
+ // Flush method.
+ _writeStream.Write(buffer, offset, count);
+ return _writeStream.FlushAsync(cancellationToken);
+ }
+
+ public void Dispose()
+ {
+ TryDispose(_readStream, () => _readStream = null);
+ TryDispose(_writeStream, () => _writeStream = null);
+ TryDispose(_socket, () => _socket = null);
+ }
+
+ private static Certificate LoadCertificate(IMqttClientChannelOptions options)
+ {
+ if (options.TlsOptions.Certificates == null || !options.TlsOptions.Certificates.Any())
+ {
+ return null;
+ }
+
+ if (options.TlsOptions.Certificates.Count > 1)
+ {
+ throw new NotSupportedException("Only one client certificate is supported for UWP.");
+ }
+
+ return new Certificate(options.TlsOptions.Certificates.First().AsBuffer());
+ }
+
+ private IEnumerable ResolveIgnorableServerCertificateErrors()
+ {
+ if (CustomIgnorableServerCertificateErrorsResolver != null)
+ {
+ return CustomIgnorableServerCertificateErrorsResolver(_options);
+ }
+
+ var result = new List();
+
+ if (_options.TlsOptions.IgnoreCertificateRevocationErrors)
+ {
+ result.Add(ChainValidationResult.RevocationInformationMissing);
+ //_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Revoked); Not supported.
+ result.Add(ChainValidationResult.RevocationFailure);
+ }
+
+ if (_options.TlsOptions.IgnoreCertificateChainErrors)
+ {
+ result.Add(ChainValidationResult.IncompleteChain);
+ }
+
+ if (_options.TlsOptions.AllowUntrustedCertificates)
+ {
+ result.Add(ChainValidationResult.Untrusted);
+ }
+
+ return result;
+ }
+
+ private void CreateStreams()
+ {
+ // Attention! Do not set the buffer for the read method. This will
+ // limit the internal buffer and the read operation will hang forever
+ // if more data than the buffer size was received.
+ _readStream = _socket.InputStream.AsStreamForRead();
+
+ _writeStream = _socket.OutputStream.AsStreamForWrite(_bufferSize);
+ }
+
+ private static void TryDispose(IDisposable disposable, Action afterDispose)
+ {
+ try
+ {
+ disposable?.Dispose();
+ }
+ catch (ObjectDisposedException)
+ {
+ }
+ catch (NullReferenceException)
+ {
+ }
+ finally
+ {
+ afterDispose();
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.cs
index 9a68e55..12fd2bb 100644
--- a/Source/MQTTnet/Implementations/MqttTcpChannel.cs
+++ b/Source/MQTTnet/Implementations/MqttTcpChannel.cs
@@ -1,3 +1,4 @@
+#if !WINDOWS_UWP
using System;
using System.Net.Security;
using System.Net.Sockets;
@@ -71,7 +72,7 @@ namespace MQTTnet.Implementations
// Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430
using (cancellationToken.Register(() => socket.Dispose()))
{
-#if NET452
+#if NET452 || NET461
await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, _options.Server, _options.GetPort(), null).ConfigureAwait(false);
#else
await socket.ConnectAsync(_options.Server, _options.GetPort()).ConfigureAwait(false);
@@ -219,4 +220,5 @@ namespace MQTTnet.Implementations
return certificates;
}
}
-}
\ No newline at end of file
+}
+#endif
diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs
new file mode 100644
index 0000000..3b24bd1
--- /dev/null
+++ b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs
@@ -0,0 +1,122 @@
+#if WINDOWS_UWP
+using Windows.Networking.Sockets;
+using MQTTnet.Adapter;
+using MQTTnet.Diagnostics;
+using MQTTnet.Formatter;
+using MQTTnet.Server;
+using System;
+using System.Runtime.InteropServices.WindowsRuntime;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading.Tasks;
+
+namespace MQTTnet.Implementations
+{
+ public class MqttTcpServerAdapter : IMqttServerAdapter
+ {
+ private readonly IMqttNetChildLogger _logger;
+
+ private IMqttServerOptions _options;
+ private StreamSocketListener _listener;
+
+ public MqttTcpServerAdapter(IMqttNetChildLogger logger)
+ {
+ if (logger == null) throw new ArgumentNullException(nameof(logger));
+
+ _logger = logger.CreateChildLogger(nameof(MqttTcpServerAdapter));
+ }
+
+ public Func ClientHandler { get; set; }
+
+ public async Task StartAsync(IMqttServerOptions options)
+ {
+ _options = options ?? throw new ArgumentNullException(nameof(options));
+
+ if (_listener != null) throw new InvalidOperationException("Server is already started.");
+
+ if (options.DefaultEndpointOptions.IsEnabled)
+ {
+ _listener = new StreamSocketListener();
+
+ // This also affects the client sockets.
+ _listener.Control.NoDelay = options.DefaultEndpointOptions.NoDelay;
+ _listener.Control.KeepAlive = true;
+ _listener.Control.QualityOfService = SocketQualityOfService.LowLatency;
+ _listener.ConnectionReceived += OnConnectionReceivedAsync;
+
+ await _listener.BindServiceNameAsync(options.DefaultEndpointOptions.Port.ToString(), SocketProtectionLevel.PlainSocket);
+ }
+
+ if (options.TlsEndpointOptions.IsEnabled)
+ {
+ throw new NotSupportedException("TLS servers are not supported for UWP apps.");
+ }
+ }
+
+ public Task StopAsync()
+ {
+ if (_listener != null)
+ {
+ _listener.ConnectionReceived -= OnConnectionReceivedAsync;
+ }
+
+ return Task.FromResult(0);
+ }
+
+ public void Dispose()
+ {
+ _listener?.Dispose();
+ _listener = null;
+ }
+
+ private async void OnConnectionReceivedAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
+ {
+ try
+ {
+ var clientHandler = ClientHandler;
+ if (clientHandler != null)
+ {
+ X509Certificate2 clientCertificate = null;
+
+ if (args.Socket.Control.ClientCertificate != null)
+ {
+ try
+ {
+ clientCertificate = new X509Certificate2(args.Socket.Control.ClientCertificate.GetCertificateBlob().ToArray());
+ }
+ catch (Exception exception)
+ {
+ _logger.Warning(exception, "Unable to convert UWP certificate to X509Certificate2.");
+ }
+ }
+
+ using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(args.Socket, clientCertificate, _options), new MqttPacketFormatterAdapter(), _logger))
+ {
+ await clientHandler(clientAdapter).ConfigureAwait(false);
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ if (exception is ObjectDisposedException)
+ {
+ // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
+ return;
+ }
+
+ _logger.Error(exception, "Error while handling client connection.");
+ }
+ finally
+ {
+ try
+ {
+ args.Socket.Dispose();
+ }
+ catch (Exception exception)
+ {
+ _logger.Error(exception, "Error while cleaning up client connection");
+ }
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs
index b1ec182..e3dcab8 100644
--- a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs
+++ b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs
@@ -1,4 +1,5 @@
-using System;
+#if !WINDOWS_UWP
+using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
@@ -127,4 +128,5 @@ namespace MQTTnet.Implementations
return clientHandler(channelAdapter);
}
}
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file
diff --git a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs
index 93b247f..d57888e 100644
--- a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs
+++ b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs
@@ -1,4 +1,5 @@
-using System;
+#if !WINDOWS_UWP
+using System;
using System.IO;
using System.Net;
using System.Net.Security;
@@ -95,7 +96,7 @@ namespace MQTTnet.Implementations
{
_socket?.Dispose();
-#if NETSTANDARD1_3 || NETSTANDARD2_0
+#if NETSTANDARD1_3 || NETSTANDARD2_0 || NET461 || NET472
_tlsCertificate?.Dispose();
#endif
}
@@ -106,7 +107,7 @@ namespace MQTTnet.Implementations
{
try
{
-#if NET452
+#if NET452 || NET461
var clientSocket = await Task.Factory.FromAsync(_socket.BeginAccept, _socket.EndAccept, null).ConfigureAwait(false);
#else
var clientSocket = await _socket.AcceptAsync().ConfigureAwait(false);
@@ -223,4 +224,5 @@ namespace MQTTnet.Implementations
}
}
}
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file
diff --git a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs
index e27cd09..38e4342 100644
--- a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs
+++ b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs
@@ -161,8 +161,10 @@ namespace MQTTnet.Implementations
return null;
}
-#if NETSTANDARD1_3
- throw new NotSupportedException("Proxies are not supported in netstandard1.3.");
+#if WINDOWS_UWP
+ throw new NotSupportedException("Proxies are not supported in UWP.");
+#elif NETSTANDARD1_3
+ throw new NotSupportedException("Proxies are not supported in netstandard 1.3.");
#else
var proxyUri = new Uri(_options.ProxyOptions.Address);
diff --git a/Source/MQTTnet/MQTTnet.csproj b/Source/MQTTnet/MQTTnet.csproj
index 1616d73..61ca517 100644
--- a/Source/MQTTnet/MQTTnet.csproj
+++ b/Source/MQTTnet/MQTTnet.csproj
@@ -2,7 +2,8 @@
netstandard1.3;netstandard2.0
- $(TargetFrameworks);net452
+ $(TargetFrameworks);net452;net461
+ $(TargetFrameworks);uap10.0
MQTTnet
MQTTnet
False
@@ -15,13 +16,30 @@
false
+
+ false
+ UAP,Version=v10.0
+ UAP
+ 10.0.17134.0
+ 10.0.10586.212
+ .NETCore
+ v5.0
+ $(DefineConstants);WINDOWS_UWP
+ en
+ $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets
+
+
Full
+
+
-
+
@@ -35,7 +53,14 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs
index 0f21728..c25af84 100644
--- a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs
+++ b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs
@@ -95,6 +95,7 @@ namespace MQTTnet.Server
return this;
}
+#if !WINDOWS_UWP
public MqttServerOptionsBuilder WithClientCertificate(RemoteCertificateValidationCallback validationCallback = null, bool checkCertificateRevocation = false)
{
_options.TlsEndpointOptions.ClientCertificateRequired = true;
@@ -102,6 +103,7 @@ namespace MQTTnet.Server
_options.TlsEndpointOptions.RemoteCertificateValidationCallback = validationCallback;
return this;
}
+#endif
public MqttServerOptionsBuilder WithoutEncryptedEndpoint()
{
@@ -109,12 +111,14 @@ namespace MQTTnet.Server
return this;
}
+#if !WINDOWS_UWP
public MqttServerOptionsBuilder WithRemoteCertificateValidationCallback(RemoteCertificateValidationCallback value)
{
_options.TlsEndpointOptions.RemoteCertificateValidationCallback = value;
return this;
}
-
+#endif
+
public MqttServerOptionsBuilder WithStorage(IMqttServerStorage value)
{
_options.Storage = value;
diff --git a/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs b/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs
index 29776aa..7f305fe 100644
--- a/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs
+++ b/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs
@@ -12,6 +12,10 @@ namespace MQTTnet.Server
public bool NoDelay { get; set; } = true;
+#if WINDOWS_UWP
+ public int BufferSize { get; set; } = 4096;
+#endif
+
public IPAddress BoundInterNetworkAddress { get; set; } = IPAddress.Any;
public IPAddress BoundInterNetworkV6Address { get; set; } = IPAddress.IPv6Any;
diff --git a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs
index c9c7791..9bf325b 100644
--- a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs
+++ b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs
@@ -17,8 +17,10 @@ namespace MQTTnet.Server
public bool ClientCertificateRequired { get; set; }
public bool CheckCertificateRevocation { get; set; }
- public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; }
+#if !WINDOWS_UWP
+ public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; }
+#endif
public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12;
}
}
diff --git a/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs b/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs
index 13085b5..94abc41 100644
--- a/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs
+++ b/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs
@@ -653,7 +653,18 @@ namespace MQTTnet.TestApp.UniversalWindows
}
// ----------------------------------
-
+
+ // For UWP apps:
+ MqttTcpChannel.CustomIgnorableServerCertificateErrorsResolver = o =>
+ {
+ if (o.Server == "server_with_revoked_cert")
+ {
+ return new[] { ChainValidationResult.Revoked };
+ }
+
+ return new ChainValidationResult[0];
+ };
+
{
// Start a MQTT server.
var mqttServer = new MqttFactory().CreateMqttServer();