mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-16 17:23:04 +08:00
Merge branch 'master' into feature/low_level_client
This commit is contained in:
@@ -22,6 +22,9 @@
|
||||
* [Server] Added interceptor for unsubscriptions.
|
||||
* [MQTTnet.Server] Added interceptor for unsubscriptions.
|
||||
* [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1
|
||||
* [Core] Added MqttApplicationMessage.GetUserProperty() convenience method (thanks to @PMExtra).
|
||||
* [Client] Support WithConnectionUri to configure client (thanks to @PMExtra).
|
||||
* [Server] Removed exceptions when user properties are set with MQTT protocol version 3.1
|
||||
* [LowLevelMqttClient] Added low level MQTT client in order to provide more flexibility when using the MQTT protocol. This client requires detailed knowledge about the MQTT protocol.
|
||||
</releaseNotes>
|
||||
<copyright>Copyright Christian Kratky 2016-2020</copyright>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using MQTTnet.Client.Options;
|
||||
|
||||
namespace MQTTnet.Extensions
|
||||
{
|
||||
public static class MqttClientOptionsBuilderExtension
|
||||
{
|
||||
public static MqttClientOptionsBuilder WithConnectionUri(this MqttClientOptionsBuilder builder, Uri uri)
|
||||
{
|
||||
var port = uri.IsDefaultPort ? null : (int?) uri.Port;
|
||||
switch (uri.Scheme.ToLower())
|
||||
{
|
||||
case "tcp":
|
||||
case "mqtt":
|
||||
builder.WithTcpServer(uri.Host, port);
|
||||
break;
|
||||
|
||||
case "mqtts":
|
||||
builder.WithTcpServer(uri.Host, port).WithTls();
|
||||
break;
|
||||
|
||||
case "ws":
|
||||
case "wss":
|
||||
builder.WithWebSocketServer(uri.ToString());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentException("Unexpected scheme in uri.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(uri.UserInfo))
|
||||
{
|
||||
var userInfo = uri.UserInfo.Split(':');
|
||||
var username = userInfo[0];
|
||||
var password = userInfo.Length > 1 ? userInfo[1] : "";
|
||||
builder.WithCredentials(username, password);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static MqttClientOptionsBuilder WithConnectionUri(this MqttClientOptionsBuilder builder, string uri)
|
||||
{
|
||||
return WithConnectionUri(builder, new Uri(uri, UriKind.Absolute));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace MQTTnet.Extensions
|
||||
{
|
||||
public static class UserPropertyExtension
|
||||
{
|
||||
public static string GetUserProperty(this MqttApplicationMessage message, string propertyName, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase)
|
||||
{
|
||||
if (message == null) throw new ArgumentNullException(nameof(message));
|
||||
if (propertyName == null) throw new ArgumentNullException(nameof(propertyName));
|
||||
|
||||
return message.UserProperties?.SingleOrDefault(up => up.Name.Equals(propertyName, comparisonType))?.Value;
|
||||
}
|
||||
|
||||
public static T GetUserProperty<T>(this MqttApplicationMessage message, string propertyName, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase)
|
||||
{
|
||||
var value = GetUserProperty(message, propertyName, comparisonType);
|
||||
|
||||
var typeDescriptor = TypeDescriptor.GetConverter(typeof(T));
|
||||
try
|
||||
{
|
||||
return (T) typeDescriptor.ConvertFromString(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot convert value({value ?? "null"}) of UserProperty({propertyName}) to {typeof(T).FullName}.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,11 +20,6 @@ namespace MQTTnet.Formatter.V3
|
||||
{
|
||||
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
|
||||
|
||||
if (applicationMessage.UserProperties?.Any() == true)
|
||||
{
|
||||
throw new MqttProtocolViolationException("User properties are not supported in MQTT version 3.");
|
||||
}
|
||||
|
||||
return new MqttPublishPacket
|
||||
{
|
||||
Topic = applicationMessage.Topic,
|
||||
@@ -171,11 +166,6 @@ namespace MQTTnet.Formatter.V3
|
||||
{
|
||||
if (options == null) throw new ArgumentNullException(nameof(options));
|
||||
|
||||
if (options.UserProperties?.Any() == true)
|
||||
{
|
||||
throw new MqttProtocolViolationException("User properties are not supported in MQTT version 3.");
|
||||
}
|
||||
|
||||
var subscribePacket = new MqttSubscribePacket();
|
||||
subscribePacket.TopicFilters.AddRange(options.TopicFilters);
|
||||
|
||||
@@ -186,11 +176,6 @@ namespace MQTTnet.Formatter.V3
|
||||
{
|
||||
if (options == null) throw new ArgumentNullException(nameof(options));
|
||||
|
||||
if (options.UserProperties?.Any() == true)
|
||||
{
|
||||
throw new MqttProtocolViolationException("User properties are not supported in MQTT version 3.");
|
||||
}
|
||||
|
||||
var unsubscribePacket = new MqttUnsubscribePacket();
|
||||
unsubscribePacket.TopicFilters.AddRange(options.TopicFilters);
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='netstandard1.3'">
|
||||
<PackageReference Include="System.ComponentModel.TypeConverter" Version="4.3.0" />
|
||||
<PackageReference Include="System.Net.Security" Version="4.3.2" />
|
||||
<PackageReference Include="System.Net.WebSockets" Version="4.3.0" />
|
||||
<PackageReference Include="System.Net.WebSockets.Client" Version="4.3.2" />
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Extensions;
|
||||
using MQTTnet.Packets;
|
||||
|
||||
namespace MQTTnet.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class MqttApplicationMessage_Tests
|
||||
{
|
||||
[TestMethod]
|
||||
public void GetUserProperty_Test()
|
||||
{
|
||||
var message = new MqttApplicationMessage
|
||||
{
|
||||
UserProperties = new List<MqttUserProperty>
|
||||
{
|
||||
new MqttUserProperty("foo", "bar"),
|
||||
new MqttUserProperty("value", "1011"),
|
||||
new MqttUserProperty("CASE", "insensitive")
|
||||
}
|
||||
};
|
||||
|
||||
Assert.AreEqual("bar", message.GetUserProperty("foo"));
|
||||
Assert.AreEqual(1011, message.GetUserProperty<int>("value"));
|
||||
Assert.AreEqual("insensitive", message.GetUserProperty("case"));
|
||||
Assert.AreEqual(null, message.GetUserProperty("nonExists"));
|
||||
Assert.AreEqual(null, message.GetUserProperty<int?>("nonExists"));
|
||||
Assert.ThrowsException<InvalidOperationException>(() => message.GetUserProperty<int>("nonExists"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client.Options;
|
||||
using MQTTnet.Extensions;
|
||||
|
||||
namespace MQTTnet.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class MqttClientOptionsBuilder_Tests
|
||||
{
|
||||
[TestMethod]
|
||||
public void WithConnectionUri_Credential_Test()
|
||||
{
|
||||
var options = new MqttClientOptionsBuilder()
|
||||
.WithConnectionUri("mqtt://user:password@127.0.0.1")
|
||||
.Build();
|
||||
Assert.AreEqual("user", options.Credentials.Username);
|
||||
Assert.IsTrue(Encoding.UTF8.GetBytes("password").SequenceEqual(options.Credentials.Password));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user