diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 1941a25..24dc74f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Bug report about: Create a report to help us improve. title: '' -labels: '' +labels: 'bug' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md index fb7bdc3..3e9c17d 100644 --- a/.github/ISSUE_TEMPLATE/custom.md +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -2,7 +2,7 @@ name: Custom issue template about: Do you have a question related to the project? Use this template. title: '' -labels: '' +labels: 'question' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index c76e79f..d3915d5 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project. title: '' -labels: '' +labels: 'feature-request' assignees: '' --- diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index 32b02ca..cc9aeaa 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -11,14 +11,7 @@ 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] Converted all pending methods to use async/await. -* [Core] Fixed an issue when serializing a PubRec (QoS 2) packet for MQTTv5. -* [Client] Fixed an issue when checking for revoked SSL certificates (thanks to @cslutgen). -* [RpcClient] Added support for custom topic generation strategies. -* [Server] Refactoring of server certificate password classes (BREAKING CHANGE!). -* [Server] Fixed an issue with empty server certificate passwords (thanks to @SeppPenner). -* [MQTTnet.Server] Added support for certificate passwords (BREAKING CHANGE IN CONFIG!) -* [MQTTnet.AspNetCore] Fixed an issue with MQTTv5 package serialization (#743, thanks to @JanEggers, @pcbing). +* [Server] Added support for assigned client IDs (MQTTv5 only) (thanks to @bcrosnier). 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 diff --git a/Build/build.ps1 b/Build/build.ps1 index 57a60f6..bd193d6 100644 --- a/Build/build.ps1 +++ b/Build/build.ps1 @@ -12,6 +12,13 @@ Write-Host "Nuget version = $nugetVersion" Write-Host "MSBuild path = $msbuild" Write-Host +# Build and execute tests +&$msbuild ..\Tests\MQTTnet.Core.Tests\MQTTnet.Tests.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netcoreapp2.1" /verbosity:m +&$msbuild ..\Tests\MQTTnet.AspNetCore.Tests\MQTTnet.AspNetCore.Tests.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netcoreapp2.1" /verbosity:m + +vstest.console.exe ..\Tests\MQTTnet.Core.Tests\bin\Release\netcoreapp2.1\MQTTnet.Tests.dll +vstest.console.exe ..\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp2.1\MQTTnet.AspNetCore.Tests.dll + # 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" @@ -43,13 +50,6 @@ Write-Host &$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" -# Build and execute tests -&$msbuild ..\Tests\MQTTnet.Core.Tests\MQTTnet.Tests.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netcoreapp2.1" /verbosity:m -&$msbuild ..\Tests\MQTTnet.AspNetCore.Tests\MQTTnet.AspNetCore.Tests.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netcoreapp2.1" /verbosity:m - -vstest.console.exe ..\Tests\MQTTnet.Core.Tests\bin\Release\netcoreapp2.1\MQTTnet.Tests.dll -vstest.console.exe ..\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp2.1\MQTTnet.AspNetCore.Tests.dll - # Create NuGet packages. Invoke-WebRequest -Uri "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -OutFile "nuget.exe" diff --git a/Source/MQTTnet.Server/Mqtt/MqttApplicationMessageInterceptor.cs b/Source/MQTTnet.Server/Mqtt/MqttApplicationMessageInterceptor.cs index 00eb0e7..135a583 100644 --- a/Source/MQTTnet.Server/Mqtt/MqttApplicationMessageInterceptor.cs +++ b/Source/MQTTnet.Server/Mqtt/MqttApplicationMessageInterceptor.cs @@ -22,7 +22,8 @@ namespace MQTTnet.Server.Mqtt { try { - var sessionItems = (PythonDictionary)context.SessionItems[MqttServerConnectionValidator.WrappedSessionItemsKey]; + // This might be not set when a message was published by the server instead of a client. + context.SessionItems.TryGetValue(MqttServerConnectionValidator.WrappedSessionItemsKey, out var sessionItems); var pythonContext = new PythonDictionary { @@ -50,4 +51,4 @@ namespace MQTTnet.Server.Mqtt return Task.CompletedTask; } } -} +} \ No newline at end of file diff --git a/Source/MQTTnet/Packets/MqttUserProperty.cs b/Source/MQTTnet/Packets/MqttUserProperty.cs index eaf9eae..dbfae07 100644 --- a/Source/MQTTnet/Packets/MqttUserProperty.cs +++ b/Source/MQTTnet/Packets/MqttUserProperty.cs @@ -13,5 +13,31 @@ namespace MQTTnet.Packets public string Name { get; } public string Value { get; } + + public override int GetHashCode() + { + return Name.GetHashCode() ^ Value.GetHashCode(); + } + + public override bool Equals(object other) + { + return Equals(other as MqttUserProperty); + } + + public bool Equals(MqttUserProperty other) + { + if (other == null) + { + return false; + } + + if (ReferenceEquals(other, this)) + { + return true; + } + + return string.Equals(Name, other.Name, StringComparison.Ordinal) && + string.Equals(Value, other.Value, StringComparison.Ordinal); + } } } diff --git a/Tests/MQTTnet.Core.Tests/MQTTv5/Client_Tests.cs b/Tests/MQTTnet.Core.Tests/MQTTv5/Client_Tests.cs index c4c7634..59d18fc 100644 --- a/Tests/MQTTnet.Core.Tests/MQTTv5/Client_Tests.cs +++ b/Tests/MQTTnet.Core.Tests/MQTTv5/Client_Tests.cs @@ -353,5 +353,52 @@ namespace MQTTnet.Tests.MQTTv5 await server.StopAsync(); } } + + [TestMethod] + public async Task Publish_And_Receive_New_Properties() + { + using (var testEnvironment = new TestEnvironment()) + { + await testEnvironment.StartServerAsync(); + + var receiver = await testEnvironment.ConnectClientAsync(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500)); + await receiver.SubscribeAsync("#"); + + MqttApplicationMessage receivedMessage = null; + receiver.UseApplicationMessageReceivedHandler(c => + { + receivedMessage = c.ApplicationMessage; + }); + + var sender = await testEnvironment.ConnectClientAsync(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500)); + + var applicationMessage = new MqttApplicationMessageBuilder() + .WithTopic("Hello") + .WithPayload("World") + .WithAtMostOnceQoS() + .WithUserProperty("x", "1") + .WithUserProperty("y", "2") + .WithResponseTopic("response") + .WithContentType("text") + .WithMessageExpiryInterval(50) + .WithCorrelationData(new byte[12]) + .WithTopicAlias(2) + .Build(); + + await sender.PublishAsync(applicationMessage); + + await Task.Delay(500); + + Assert.IsNotNull(receivedMessage); + Assert.AreEqual(applicationMessage.Topic, receivedMessage.Topic); + Assert.AreEqual(applicationMessage.TopicAlias, receivedMessage.TopicAlias); + Assert.AreEqual(applicationMessage.ContentType, receivedMessage.ContentType); + Assert.AreEqual(applicationMessage.ResponseTopic, receivedMessage.ResponseTopic); + Assert.AreEqual(applicationMessage.MessageExpiryInterval, receivedMessage.MessageExpiryInterval); + CollectionAssert.AreEqual(applicationMessage.CorrelationData, receivedMessage.CorrelationData); + CollectionAssert.AreEqual(applicationMessage.Payload, receivedMessage.Payload); + CollectionAssert.AreEqual(applicationMessage.UserProperties, receivedMessage.UserProperties); + } + } } }