Merge branch 'master' of https://github.com/chkr1011/MQTTnet into feature/pending-appmsg-acknowledge

# Conflicts:
#	Source/MQTTnet/Client/MqttClient.cs
#	Source/MQTTnet/MqttApplicationMessageReceivedEventArgs.cs
This commit is contained in:
tamas.kurucsai
2021-02-20 12:55:28 +01:00
114 changed files with 1823 additions and 2110 deletions
@@ -43,7 +43,7 @@ namespace MQTTnet.Benchmarks
var channel = new TestMqttChannel(_stream);
_channelAdapter = new MqttChannelAdapter(channel, serializer, new MqttNetLogger());
_channelAdapter = new MqttChannelAdapter(channel, serializer, null, new MqttNetLogger());
}
[Benchmark]
@@ -9,6 +9,7 @@ using MQTTnet.Channel;
using MQTTnet.Formatter;
using MQTTnet.Formatter.V3;
using BenchmarkDotNet.Jobs;
using MQTTnet.Diagnostics;
namespace MQTTnet.Benchmarks
{
@@ -48,19 +49,13 @@ namespace MQTTnet.Benchmarks
{
var channel = new BenchmarkMqttChannel(_serializedPacket);
var fixedHeader = new byte[2];
var reader = new MqttPacketReader(channel);
var reader = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(new MqttPacketWriter()), null, new MqttNetLogger());
for (var i = 0; i < 10000; i++)
{
channel.Reset();
var header = reader.ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
var receivedPacket = new ReceivedMqttPacket(
header.Flags,
new MqttPacketBodyReader(_serializedPacket.Array, _serializedPacket.Count - header.RemainingLength, _serializedPacket.Array.Length), 0);
_serializer.Decode(receivedPacket);
var header = reader.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
}
}
@@ -1,23 +1,24 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Formatter;
using MQTTnet.Internal;
//using System.IO;
//using System.Threading;
//using System.Threading.Tasks;
//using Microsoft.VisualStudio.TestTools.UnitTesting;
//using MQTTnet.Formatter;
//using MQTTnet.Internal;
namespace MQTTnet.Tests
{
[TestClass]
public class MqttPacketReader_Tests
{
[TestMethod]
public async Task MqttPacketReader_EmptyStream()
{
var fixedHeader = new byte[2];
var reader = new MqttPacketReader(new TestMqttChannel(new MemoryStream()));
var readResult = await reader.ReadFixedHeaderAsync(fixedHeader, CancellationToken.None);
//namespace MQTTnet.Tests
//{
// [TestClass]
// public class MqttPacketReader_Tests
// {
// [TestMethod]
// public async Task MqttPacketReader_EmptyStream()
// {
// var fixedHeader = new byte[2];
// var reader = new MqttPacketReader(new TestMqttChannel(new MemoryStream()));
// var readResult = await reader.ReadFixedHeaderAsync(fixedHeader, CancellationToken.None);
Assert.IsTrue(readResult.ConnectionClosed);
}
}
}
// Assert.IsTrue(readResult.ConnectionClosed);
// }
// }
//}
// TODO: Fix
@@ -6,6 +6,7 @@ using System.Text;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Exceptions;
using MQTTnet.Formatter;
using MQTTnet.Formatter.V3;
@@ -22,7 +23,7 @@ namespace MQTTnet.Tests
[TestMethod]
public void DetectVersionFromMqttConnectPacket()
{
var p = new MqttConnectPacket
var packet = new MqttConnectPacket
{
ClientId = "XYZ",
Password = Encoding.UTF8.GetBytes("PASS"),
@@ -30,17 +31,26 @@ namespace MQTTnet.Tests
KeepAlivePeriod = 123,
CleanSession = true
};
var adapter = new MqttPacketFormatterAdapter(WriterFactory());
Assert.AreEqual(MqttProtocolVersion.V310, DeserializeAndDetectVersion(adapter, Serialize(p, MqttProtocolVersion.V310)));
Assert.AreEqual(MqttProtocolVersion.V311, DeserializeAndDetectVersion(adapter, Serialize(p, MqttProtocolVersion.V311)));
Assert.AreEqual(MqttProtocolVersion.V500, DeserializeAndDetectVersion(adapter, Serialize(p, MqttProtocolVersion.V500)));
Assert.AreEqual(
MqttProtocolVersion.V310,
DeserializeAndDetectVersion(new MqttPacketFormatterAdapter(new MqttPacketWriter()), Serialize(packet, MqttProtocolVersion.V310)));
Assert.AreEqual(
MqttProtocolVersion.V311,
DeserializeAndDetectVersion(new MqttPacketFormatterAdapter(new MqttPacketWriter()), Serialize(packet, MqttProtocolVersion.V311)));
Assert.AreEqual(
MqttProtocolVersion.V500,
DeserializeAndDetectVersion(new MqttPacketFormatterAdapter(new MqttPacketWriter()), Serialize(packet, MqttProtocolVersion.V500)));
var adapter = new MqttPacketFormatterAdapter(new MqttPacketWriter());
var ex = Assert.ThrowsException<MqttProtocolViolationException>(() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, new byte[0])));
Assert.AreEqual("CONNECT packet must have at least 7 bytes.", ex.Message);
ex = Assert.ThrowsException<MqttProtocolViolationException>(() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, new byte[7])));
Assert.AreEqual("Protocol '' not supported.", ex.Message);
ex = Assert.ThrowsException<MqttProtocolViolationException>(() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, new byte[] { 255, 255, 0,0,0,0,0 })));
ex = Assert.ThrowsException<MqttProtocolViolationException>(() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, new byte[] { 255, 255, 0, 0, 0, 0, 0 })));
Assert.AreEqual("Expected at least 65537 bytes but there are only 7 bytes", ex.Message);
}
@@ -205,24 +215,28 @@ namespace MQTTnet.Tests
Payload = payload
};
var buffer = serializer.Encode(publishPacket);
var testChannel = new TestMqttChannel(new MemoryStream(buffer.Array, buffer.Offset, buffer.Count));
var header = new MqttPacketReader(testChannel).ReadFixedHeaderAsync(
new byte[2],
CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
var publishPacketCopy = Roundtrip(publishPacket);
var eof = buffer.Offset + buffer.Count;
//var buffer = serializer.Encode(publishPacket);
//var testChannel = new TestMqttChannel(new MemoryStream(buffer.Array, buffer.Offset, buffer.Count));
var receivedPacket = new ReceivedMqttPacket(
header.Flags,
new MqttPacketBodyReader(buffer.Array, eof - header.RemainingLength, buffer.Count + buffer.Offset),
0);
var packet = (MqttPublishPacket)serializer.Decode(receivedPacket);
//var header = new MqttPacketReader(testChannel).ReadFixedHeaderAsync(
// new byte[2],
// CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
Assert.AreEqual(publishPacket.Topic, packet.Topic);
Assert.IsTrue(publishPacket.Payload.SequenceEqual(packet.Payload));
//var eof = buffer.Offset + buffer.Count;
//var receivedPacket = new ReceivedMqttPacket(
// header.Flags,
// new MqttPacketBodyReader(buffer.Array, eof - header.RemainingLength, buffer.Count + buffer.Offset),
// 0);
//var packet = (MqttPublishPacket)serializer.Decode(receivedPacket);
Assert.AreEqual(publishPacket.Topic, publishPacketCopy.Topic);
Assert.IsTrue(publishPacket.Payload.SequenceEqual(publishPacketCopy.Payload));
}
[TestMethod]
@@ -262,7 +276,7 @@ namespace MQTTnet.Tests
[TestMethod]
public void SerializeV500_MqttPublishPacket()
{
var prop = new MqttPublishPacketProperties {UserProperties = new List<MqttUserProperty>()};
var prop = new MqttPublishPacketProperties { UserProperties = new List<MqttUserProperty>() };
prop.ResponseTopic = "/Response";
@@ -581,15 +595,14 @@ namespace MQTTnet.Tests
DeserializeAndCompare(p, "sAIAew==");
}
private void SerializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
void SerializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
{
Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Serialize(packet, protocolVersion)));
}
private byte[] Serialize(MqttBasePacket packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
byte[] Serialize(MqttBasePacket packet, MqttProtocolVersion protocolVersion)
{
var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, WriterFactory());
return Join(serializer.Encode(packet));
return MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, WriterFactory()).Encode(packet).ToArray();
}
protected virtual IMqttPacketWriter WriterFactory()
@@ -602,83 +615,92 @@ namespace MQTTnet.Tests
return new MqttPacketBodyReader(data, 0, data.Length);
}
private void DeserializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
void DeserializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
{
var writer = WriterFactory();
var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
var buffer1 = serializer.Encode(packet);
using (var headerStream = new MemoryStream(Join(buffer1)))
using (var headerStream = new MemoryStream(buffer1.ToArray()))
{
var channel = new TestMqttChannel(headerStream);
var fixedHeader = new byte[2];
var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
var adapter = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(protocolVersion, writer), null, new MqttNetLogger());
var receivedPacket = adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
{
var reader = ReaderFactory(bodyStream.ToArray());
var deserializedPacket = serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
var buffer2 = serializer.Encode(deserializedPacket);
var buffer2 = serializer.Encode(receivedPacket);
Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(buffer2)));
}
Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(buffer2.ToArray()));
//adapter.ReceivePacketAsync(CancellationToken.None);
//var fixedHeader = new byte[2];
//var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
//using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
//{
// var reader = ReaderFactory(bodyStream.ToArray());
// var deserializedPacket = serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
// var buffer2 = serializer.Encode(deserializedPacket);
// Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(buffer2)));
//}
}
}
private T Roundtrip<T>(T packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
where T : MqttBasePacket
TPacket Roundtrip<TPacket>(TPacket packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
where TPacket : MqttBasePacket
{
var writer = WriterFactory();
var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
var buffer = serializer.Encode(packet);
var buffer1 = serializer.Encode(packet);
var channel = new TestMqttChannel(buffer.ToArray());
var adapter = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(protocolVersion, writer), null, new MqttNetLogger());
return (TPacket)adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
using (var headerStream = new MemoryStream(Join(buffer1)))
{
var channel = new TestMqttChannel(headerStream);
var fixedHeader = new byte[2];
//using (var headerStream = new MemoryStream(buffer1.ToArray()))
//{
var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, (int)header.RemainingLength))
{
var reader = ReaderFactory(bodyStream.ToArray());
return (T)serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
}
}
// //var fixedHeader = new byte[2];
// //var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
// //using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, (int)header.RemainingLength))
// //{
// // var reader = ReaderFactory(bodyStream.ToArray());
// // return (T)serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
// //}
//}
}
private MqttProtocolVersion DeserializeAndDetectVersion(MqttPacketFormatterAdapter adapter, byte[] buffer)
MqttProtocolVersion DeserializeAndDetectVersion(MqttPacketFormatterAdapter packetFormatterAdapter, byte[] buffer)
{
using (var headerStream = new MemoryStream(buffer))
{
var channel = new TestMqttChannel(headerStream);
var fixedHeader = new byte[2];
var channel = new TestMqttChannel(buffer);
var adapter = new MqttChannelAdapter(channel, packetFormatterAdapter, null, new MqttNetLogger());
var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
return packetFormatterAdapter.ProtocolVersion;
using (var bodyStream = new MemoryStream(buffer, (int)headerStream.Position, (int)header.RemainingLength))
{
var reader = ReaderFactory(bodyStream.ToArray());
var packet = new ReceivedMqttPacket(header.Flags, reader, 0);
adapter.DetectProtocolVersion(packet);
return adapter.ProtocolVersion;
}
}
}
//using (var headerStream = new MemoryStream(buffer))
//{
private static byte[] Join(params ArraySegment<byte>[] chunks)
{
var buffer = new MemoryStream();
foreach (var chunk in chunks)
{
buffer.Write(chunk.Array, chunk.Offset, chunk.Count);
}
return buffer.ToArray();
// //var fixedHeader = new byte[2];
// //var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
// //using (var bodyStream = new MemoryStream(buffer, (int)headerStream.Position, (int)header.RemainingLength))
// //{
// // var reader = ReaderFactory(bodyStream.ToArray());
// // var packet = new ReceivedMqttPacket(header.Flags, reader, 0);
// // packetFormatterAdapter.DetectProtocolVersion(packet);
// // return adapter.ProtocolVersion;
// //}
//}
}
}
}
+53 -3
View File
@@ -1,4 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Adapter;
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
@@ -6,6 +6,7 @@ using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using MQTTnet.Client.Subscribing;
using MQTTnet.Exceptions;
using MQTTnet.Protocol;
using MQTTnet.Server;
using MQTTnet.Tests.Mockups;
@@ -25,6 +26,55 @@ namespace MQTTnet.Tests
{
public TestContext TestContext { get; set; }
[TestMethod]
[DataRow("", null)]
[DataRow("", "")]
[DataRow(null, null)]
public async Task Use_Admissible_Credentials(string username, string password)
{
using (var testEnvironment = new TestEnvironment())
{
await testEnvironment.StartServerAsync();
var client = testEnvironment.CreateClient();
var clientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("localhost", testEnvironment.ServerPort)
.WithCredentials(username, password)
.Build();
var connectResult = await client.ConnectAsync(clientOptions);
Assert.IsFalse(connectResult.IsSessionPresent);
Assert.IsTrue(client.IsConnected);
}
}
[TestMethod]
public async Task Use_Username_Null_Password_Empty()
{
string username = null;
string password = string.Empty;
using (var testEnvironment = new TestEnvironment())
{
testEnvironment.IgnoreClientLogErrors = true;
await testEnvironment.StartServerAsync();
var client = testEnvironment.CreateClient();
var clientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("localhost", testEnvironment.ServerPort)
.WithCredentials(username, password)
.Build();
var ex = await Assert.ThrowsExceptionAsync<MqttConnectingFailedException>(async () => await client.ConnectAsync(clientOptions));
Assert.IsInstanceOfType(ex.InnerException, typeof(MqttProtocolViolationException));
Assert.AreEqual("Error while authenticating. If the User Name Flag is set to 0, the Password Flag MUST be set to 0 [MQTT-3.1.2-22].", ex.Message, false);
}
}
[TestMethod]
public async Task Use_Empty_Client_ID()
{
@@ -416,7 +466,7 @@ namespace MQTTnet.Tests
public async Task Publish_Multiple_Clients()
{
var receivedMessagesCount = 0;
using (var testEnvironment = new TestEnvironment(TestContext))
{
await testEnvironment.StartServerAsync();
@@ -446,7 +496,7 @@ namespace MQTTnet.Tests
}
SpinWait.SpinUntil(() => receivedMessagesCount == 1000, TimeSpan.FromSeconds(20));
Assert.AreEqual(1000, receivedMessagesCount);
}
}
@@ -6,6 +6,20 @@ namespace MQTTnet.Tests
[TestClass]
public class TopicFilterComparer_Tests
{
[TestMethod]
public void TopicFilterComparer_Plus_Match_With_Separator_Only()
{
//A Topic Name or Topic Filter consisting only of the ‘/’ character is valid
CompareAndAssert("A", "+", true);
}
[TestMethod]
public void TopicFilterComparer_Hash_Match_With_Separator_Only()
{
//A Topic Name or Topic Filter consisting only of the ‘/’ character is valid
CompareAndAssert("/", "#", true);
}
[TestMethod]
public void TopicFilterComparer_DirectMatch()
{
@@ -54,6 +68,12 @@ namespace MQTTnet.Tests
CompareAndAssert("A/B/C/D", "A/C/#", false);
}
[TestMethod]
public void TopicFilterComparer_EndMultipleLevelsWildcardMatchEmptyLevel()
{
CompareAndAssert("A/", "A/#", true);
}
[TestMethod]
public void TopicFilterComparer_AllLevelsWildcardMatch()
{
@@ -1,6 +0,0 @@
<Application
x:Class="MQTTnet.TestApp.UniversalWindows.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
RequestedTheme="Light">
</Application>
@@ -1,51 +0,0 @@
using System;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace MQTTnet.TestApp.UniversalWindows
{
sealed partial class App
{
public App()
{
InitializeComponent();
Suspending += OnSuspending;
}
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
if (!(Window.Current.Content is Frame rootFrame))
{
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
Window.Current.Activate();
}
}
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
deferral.Complete();
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

@@ -1,49 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using MQTTnet.Server;
using Newtonsoft.Json;
namespace MQTTnet.TestApp.UniversalWindows
{
public sealed class JsonServerStorage : IMqttServerStorage
{
readonly string _filename = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "Retained.json");
public Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages)
{
var json = JsonConvert.SerializeObject(messages);
File.WriteAllText(_filename, json);
return Task.CompletedTask;
}
public async Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync()
{
await Task.CompletedTask;
if (!File.Exists(_filename))
{
return new List<MqttApplicationMessage>();
}
try
{
var json = File.ReadAllText(_filename);
return JsonConvert.DeserializeObject<List<MqttApplicationMessage>>(json);
}
catch
{
return new List<MqttApplicationMessage>();
}
}
public void Clear()
{
if (File.Exists(_filename))
{
File.Delete(_filename);
}
}
}
}
@@ -1,196 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{FF1F72D6-9524-4422-9497-3CC0002216ED}</ProjectGuid>
<OutputType>AppContainerExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MQTTnet.TestApp.UniversalWindows</RootNamespace>
<AssemblyName>MQTTnet.TestApp.UniversalWindows</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.18362.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
<PackageCertificateKeyFile>MQTTnet.TestApp.UniversalWindows_TemporaryKey.pfx</PackageCertificateKeyFile>
<PackageCertificateThumbprint>1B25E1E3A70C4FEF793B882295F383301B861796</PackageCertificateThumbprint>
<RuntimeIdentifiers>win10;win10-arm;win10-arm-aot;win10-x86;win10-x86-aot;win10-x64;win10-x64-aot</RuntimeIdentifiers>
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<ItemGroup>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="JsonServerStorage.cs" />
<Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<None Include="..\..\.editorconfig">
<Link>.editorconfig</Link>
</None>
<None Include="MQTTnet.TestApp.UniversalWindows_TemporaryKey.pfx" />
</ItemGroup>
<ItemGroup>
<Content Include="Properties\Default.rd.xml" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\Square150x150Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\StoreLogo.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="MainPage.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj">
<Project>{C400533A-8EBA-4F0B-BF4D-295C3708604B}</Project>
<Name>MQTTnet.Extensions.ManagedClient</Name>
</ProjectReference>
<ProjectReference Include="..\..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj">
<Project>{c444e9c8-95fa-430e-9126-274129de16cd}</Project>
<Name>MQTTnet.Extensions.Rpc</Name>
</ProjectReference>
<ProjectReference Include="..\..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj">
<Project>{2BD01D53-4CA5-4142-BE8D-313876395E3E}</Project>
<Name>MQTTnet.Extensions.WebSocket4Net</Name>
</ProjectReference>
<ProjectReference Include="..\..\Source\MQTTnet\MQTTnet.csproj">
<Project>{3587e506-55a2-4eb3-99c7-dc01e42d25d2}</Project>
<Name>MQTTnet</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.10</Version>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
<Version>4.0.0</Version>
</PackageReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP;CODE_ANALYSIS</DefineConstants>
<NoWarn>;2008</NoWarn>
<NoStdLib>true</NoStdLib>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP;CODE_ANALYSIS</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<NoStdLib>true</NoStdLib>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
@@ -1,266 +0,0 @@
<Page
x:Class="MQTTnet.TestApp.UniversalWindows.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:server="using:MQTTnet.Server"
xmlns:status="using:MQTTnet.Server.Status"
d:DesignHeight="800"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Pivot Grid.Row="0">
<PivotItem Header="Connection">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="Margin" Value="0, 0, 10, 0"></Setter>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0">Server:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="0" x:Name="Server" Text="localhost"></TextBox>
<TextBlock Grid.Column="0" Grid.Row="1">Port:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="1" x:Name="Port" Text="1883"></TextBox>
<TextBlock Grid.Column="0" Grid.Row="2">Username:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="2" x:Name="User"></TextBox>
<TextBlock Grid.Column="0" Grid.Row="3">Password:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="3" x:Name="Password"></TextBox>
<TextBlock Grid.Column="0" Grid.Row="4">Client ID:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="4" x:Name="ClientId"></TextBox>
<TextBlock Grid.Column="0" Grid.Row="5">Keep Alive interval:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="5" x:Name="KeepAliveInterval" Text="5"></TextBox>
<TextBlock Grid.Column="0" Grid.Row="6">Transport:</TextBlock>
<StackPanel Grid.Column="1" Grid.Row="6" Orientation="Horizontal">
<RadioButton x:Name="UseTcp" IsChecked="True" GroupName="transport">TCP</RadioButton>
<RadioButton x:Name="UseWs" GroupName="transport">WS</RadioButton>
<RadioButton x:Name="UseWs4Net" GroupName="transport">WS (WebSocket4Net)</RadioButton>
<CheckBox x:Name="UseTls">Use TLS</CheckBox>
</StackPanel>
<TextBlock Grid.Column="0" Grid.Row="7">Protocol:</TextBlock>
<StackPanel Grid.Column="1" Grid.Row="7" Orientation="Horizontal">
<RadioButton x:Name="UseMqtt500" GroupName="protocol">5.0.0</RadioButton>
<RadioButton x:Name="UseMqtt311" GroupName="protocol" IsChecked="True">3.1.1</RadioButton>
<RadioButton x:Name="UseMqtt310" GroupName="protocol">3.1.0</RadioButton>
</StackPanel>
</Grid>
<CheckBox x:Name="CleanSession" IsChecked="True">Clean session</CheckBox>
<CheckBox x:Name="UseManagedClient" IsChecked="False">Use managed client</CheckBox>
<StackPanel Orientation="Horizontal">
<Button Click="Connect" Width="120" Margin="0,0,10,0">Connect</Button>
<Button Click="Disconnect" Width="120">Disconnect</Button>
</StackPanel>
</StackPanel>
</PivotItem>
<PivotItem Header="Publish">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="Margin" Value="0, 0, 10, 0"></Setter>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0">Topic:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="0" x:Name="Topic"></TextBox>
<TextBlock Grid.Column="0" Grid.Row="1">Content type:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="1" x:Name="ContentType"></TextBox>
<TextBlock Grid.Column="0" Grid.Row="2">Payload:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="2" x:Name="Payload"></TextBox>
<TextBlock Grid.Column="0" Grid.Row="3">Payload format:</TextBlock>
<StackPanel Grid.Column="1" Grid.Row="3" Orientation="Horizontal">
<RadioButton Margin="0,0,10,0" x:Name="PlainText" IsChecked="True" GroupName="payload">Plain text</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="Base64" GroupName="payload">Base64 string</RadioButton>
</StackPanel>
<TextBlock Grid.Column="0" Grid.Row="4">QoS level:</TextBlock>
<StackPanel Grid.Column="1" Grid.Row="4" Orientation="Horizontal">
<RadioButton Margin="0,0,10,0" IsChecked="True" GroupName="qos">0 (At most once)</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="QoS1" GroupName="qos">1 (At least once)</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="QoS2" GroupName="qos">2 (Exactly once)</RadioButton>
</StackPanel>
<TextBlock Grid.Column="0" Grid.Row="5">Response topic:</TextBlock>
<TextBox Grid.Column="1" Grid.Row="5" x:Name="ResponseTopic"></TextBox>
</Grid>
<CheckBox x:Name="Retain">Retain</CheckBox>
<Button Click="Publish" Width="120">Publish</Button>
</StackPanel>
</PivotItem>
<PivotItem Header="Execute RPC">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock>Method:</TextBlock>
<TextBox x:Name="RpcMethod"></TextBox>
<TextBlock>Payload:</TextBlock>
<TextBox x:Name="RpcPayload"></TextBox>
<StackPanel Orientation="Horizontal">
<RadioButton x:Name="RpcText" IsChecked="True" GroupName="payload">Text</RadioButton>
<RadioButton x:Name="RpcBase64" GroupName="payload">Base64</RadioButton>
</StackPanel>
<TextBlock>QoS:</TextBlock>
<StackPanel Orientation="Horizontal">
<RadioButton Margin="0,0,10,0" x:Name="RpcQoS0" GroupName="qos" IsChecked="True">0 (At most once)</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="RpcQoS1" GroupName="qos">1 (At least once)</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="RpcQoS2" GroupName="qos">2 (Exactly once)</RadioButton>
</StackPanel>
<TextBlock>Responses:</TextBlock>
<ListBox MinHeight="50" MaxHeight="250" x:Name="RpcResponses" Margin="0,0,0,10">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding}" FontFamily="Consolas" FontSize="12"></ContentPresenter>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Orientation="Horizontal">
<Button Click="ExecuteRpc" Width="120" Margin="0,0,10,0">Execute</Button>
<Button Click="ClearRpcResponses" Width="200">Clear responses</Button>
</StackPanel>
</StackPanel>
</PivotItem>
<PivotItem Header="Subscribe">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock>Topic:</TextBlock>
<TextBox x:Name="SubscribeTopic"></TextBox>
<TextBlock>QoS:</TextBlock>
<StackPanel Orientation="Horizontal">
<RadioButton Margin="0,0,10,0" IsChecked="True" GroupName="sqos">0 (At most once)</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="SubscribeQoS1" GroupName="sqos">1 (At least once)</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="SubscribeQoS2" GroupName="sqos">2 (Exactly once)</RadioButton>
</StackPanel>
<TextBlock>Received messages:</TextBlock>
<CheckBox x:Name="AddReceivedMessagesToList" IsChecked="True">Add received messages to list</CheckBox>
<ListBox MinHeight="50" MaxHeight="250" x:Name="ReceivedMessages" Margin="0,0,0,10">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding}" FontFamily="Consolas" FontSize="12"></ContentPresenter>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Orientation="Horizontal">
<Button Click="Subscribe" Width="120" Margin="0,0,10,0">Subscribe</Button>
<Button Click="Unsubscribe" Width="120" Margin="0,0,10,0">Unsubscribe</Button>
<Button Click="ClearReceivedMessages" Width="200">Clear received messages</Button>
</StackPanel>
</StackPanel>
</PivotItem>
<PivotItem Header="Server">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock>Port:</TextBlock>
<TextBox x:Name="ServerPort" Text="1883"></TextBox>
<CheckBox x:Name="ServerPersistRetainedMessages" IsChecked="True">Persist retained messages in JSON format</CheckBox>
<CheckBox x:Name="ServerClearRetainedMessages">Clear previously retained messages on startup</CheckBox>
<CheckBox x:Name="ServerAllowPersistentSessions">Allow persistent sessions</CheckBox>
<StackPanel Orientation="Horizontal">
<Button Width="120" Margin="0,0,10,0" Click="StartServer">Start</Button>
<Button Width="120" Margin="0,0,10,0" Click="StopServer">Stop</Button>
</StackPanel>
</StackPanel>
</PivotItem>
<PivotItem Header="Sessions">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Horizontal">
<Button Width="120" Margin="0,0,10,0" Click="RefreshSessions">Refresh</Button>
<Button Width="120" Margin="0,0,10,0" Click="ClearSessions">Clear</Button>
</StackPanel>
<ListView ItemsSource="{Binding}" x:Name="ListViewSessions">
<ListView.ItemTemplate>
<DataTemplate x:DataType="status:IMqttClientStatus">
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="0,0,10,0"></Setter>
</Style>
</StackPanel.Resources>
<TextBlock Text="{Binding ClientId}"></TextBlock>
<TextBlock Text="{Binding Endpoint}"></TextBlock>
<TextBlock Text="{Binding LastPacketReceived}"></TextBlock>
<TextBlock Text="{Binding LastNonKeepAlivePacketReceived}"></TextBlock>
<TextBlock Text="{Binding ProtocolVersion}"></TextBlock>
<TextBlock Text="{Binding Session}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</PivotItem>
<PivotItem Header="Log">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Click="ClearLog" Width="120">Clear</Button>
</StackPanel>
</PivotItem>
</Pivot>
<ScrollViewer Grid.Row="1" Margin="12,10,12,0" Background="Black" Foreground="WhiteSmoke" FontFamily="Consolas" HorizontalScrollMode="Enabled" VerticalScrollMode="Enabled" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
<TextBlock x:Name="Trace" FontSize="11"></TextBlock>
</ScrollViewer>
</Grid>
</Page>
@@ -1,834 +0,0 @@
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Diagnostics;
using MQTTnet.Exceptions;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Extensions.Rpc;
using MQTTnet.Extensions.Rpc.Options;
using MQTTnet.Extensions.WebSocket4Net;
using MQTTnet.Formatter;
using MQTTnet.Implementations;
using MQTTnet.Protocol;
using MQTTnet.Server;
using MQTTnet.Server.Status;
using System;
using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using Windows.Security.Cryptography.Certificates;
using Windows.UI.Core;
using Windows.UI.Xaml;
namespace MQTTnet.TestApp.UniversalWindows
{
public sealed partial class MainPage
{
private readonly ConcurrentQueue<MqttNetLogMessage> _traceMessages = new ConcurrentQueue<MqttNetLogMessage>();
private readonly ObservableCollection<IMqttClientStatus> _sessions = new ObservableCollection<IMqttClientStatus>();
private IMqttClient _mqttClient;
private IManagedMqttClient _managedMqttClient;
private IMqttServer _mqttServer;
public MainPage()
{
InitializeComponent();
ClientId.Text = Guid.NewGuid().ToString("D");
MqttNetGlobalLogger.LogMessagePublished += OnTraceMessagePublished;
}
private async void OnTraceMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e)
{
_traceMessages.Enqueue(e.LogMessage);
await UpdateLogAsync();
}
private async Task UpdateLogAsync()
{
while (_traceMessages.Count > 100)
{
_traceMessages.TryDequeue(out _);
}
var logText = new StringBuilder();
foreach (var traceMessage in _traceMessages)
{
logText.AppendFormat(
"[{0:yyyy-MM-dd HH:mm:ss.fff}] [{1}] [{2}] [{3}] [{4}]{5}",
traceMessage.Timestamp,
traceMessage.Level,
traceMessage.Source,
traceMessage.ThreadId,
traceMessage.Message,
Environment.NewLine);
if (traceMessage.Exception != null)
{
logText.AppendLine(traceMessage.Exception.ToString());
}
}
await Trace.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
{
Trace.Text = logText.ToString();
});
}
private async void Connect(object sender, RoutedEventArgs e)
{
var mqttFactory = new MqttFactory();
var tlsOptions = new MqttClientTlsOptions
{
UseTls = UseTls.IsChecked == true,
IgnoreCertificateChainErrors = true,
IgnoreCertificateRevocationErrors = true,
AllowUntrustedCertificates = true
};
var options = new MqttClientOptions
{
ClientId = ClientId.Text,
ProtocolVersion = MqttProtocolVersion.V500
};
if (UseTcp.IsChecked == true)
{
options.ChannelOptions = new MqttClientTcpOptions
{
Server = Server.Text,
Port = int.Parse(Port.Text),
TlsOptions = tlsOptions
};
}
if (UseWs.IsChecked == true)
{
options.ChannelOptions = new MqttClientWebSocketOptions
{
Uri = Server.Text,
TlsOptions = tlsOptions
};
}
if (UseWs4Net.IsChecked == true)
{
options.ChannelOptions = new MqttClientWebSocketOptions
{
Uri = Server.Text,
TlsOptions = tlsOptions
};
mqttFactory.UseWebSocket4Net();
}
if (options.ChannelOptions == null)
{
throw new InvalidOperationException();
}
if (!string.IsNullOrEmpty(User.Text))
{
options.Credentials = new MqttClientCredentials
{
Username = User.Text,
Password = Encoding.UTF8.GetBytes(Password.Text)
};
}
options.CleanSession = CleanSession.IsChecked == true;
options.KeepAlivePeriod = TimeSpan.FromSeconds(double.Parse(KeepAliveInterval.Text));
if (UseMqtt310.IsChecked == true)
{
options.ProtocolVersion = MqttProtocolVersion.V310;
}
else if (UseMqtt311.IsChecked == true)
{
options.ProtocolVersion = MqttProtocolVersion.V311;
}
else if (UseMqtt500.IsChecked == true)
{
options.ProtocolVersion = MqttProtocolVersion.V500;
}
try
{
if (_mqttClient != null)
{
await _mqttClient.DisconnectAsync();
_mqttClient.UseApplicationMessageReceivedHandler(HandleReceivedApplicationMessage);
_mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(x => OnConnected());
_mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(x => OnDisconnected());
}
if (UseManagedClient.IsChecked == true)
{
_managedMqttClient = mqttFactory.CreateManagedMqttClient();
_managedMqttClient.UseApplicationMessageReceivedHandler(HandleReceivedApplicationMessage);
_managedMqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(x => OnConnected());
_managedMqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(x => OnDisconnected());
await _managedMqttClient.StartAsync(new ManagedMqttClientOptions
{
ClientOptions = options
});
}
else
{
_mqttClient = mqttFactory.CreateMqttClient();
_mqttClient.UseApplicationMessageReceivedHandler(HandleReceivedApplicationMessage);
_mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(x => OnConnected());
_mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(x => OnDisconnected());
await _mqttClient.ConnectAsync(options);
}
}
catch (Exception exception)
{
Trace.Text += exception + Environment.NewLine;
}
}
private void OnDisconnected()
{
_traceMessages.Enqueue(new MqttNetLogMessage
{
Timestamp = DateTime.UtcNow,
ThreadId = -1,
Level = MqttNetLogLevel.Info,
Message = "! DISCONNECTED EVENT FIRED",
});
Task.Run(UpdateLogAsync);
}
private void OnConnected()
{
_traceMessages.Enqueue(new MqttNetLogMessage
{
Timestamp = DateTime.UtcNow,
ThreadId = -1,
Level = MqttNetLogLevel.Info,
Message = "! CONNECTED EVENT FIRED",
});
Task.Run(UpdateLogAsync);
}
private async Task HandleReceivedApplicationMessage(MqttApplicationMessageReceivedEventArgs eventArgs)
{
var item = $"Timestamp: {DateTime.Now:O} | Topic: {eventArgs.ApplicationMessage.Topic} | Payload: {eventArgs.ApplicationMessage.ConvertPayloadToString()} | QoS: {eventArgs.ApplicationMessage.QualityOfServiceLevel}";
await Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
{
if (AddReceivedMessagesToList.IsChecked == true)
{
ReceivedMessages.Items.Add(item);
}
});
}
private async void Publish(object sender, RoutedEventArgs e)
{
try
{
var qos = MqttQualityOfServiceLevel.AtMostOnce;
if (QoS1.IsChecked == true)
{
qos = MqttQualityOfServiceLevel.AtLeastOnce;
}
if (QoS2.IsChecked == true)
{
qos = MqttQualityOfServiceLevel.ExactlyOnce;
}
var payload = Array.Empty<byte>();
if (PlainText.IsChecked == true)
{
payload = Encoding.UTF8.GetBytes(Payload.Text);
}
if (Base64.IsChecked == true)
{
payload = Convert.FromBase64String(Payload.Text);
}
var message = new MqttApplicationMessageBuilder()
.WithContentType(ContentType.Text)
.WithResponseTopic(ResponseTopic.Text)
.WithTopic(Topic.Text)
.WithPayload(payload)
.WithQualityOfServiceLevel(qos)
.WithRetainFlag(Retain.IsChecked == true)
.Build();
if (_mqttClient != null)
{
await _mqttClient.PublishAsync(message);
}
if (_managedMqttClient != null)
{
await _managedMqttClient.PublishAsync(message);
}
}
catch (Exception exception)
{
Trace.Text += exception + Environment.NewLine;
}
}
private async void Disconnect(object sender, RoutedEventArgs e)
{
try
{
if (_mqttClient != null)
{
await _mqttClient.DisconnectAsync();
_mqttClient.Dispose();
_mqttClient = null;
}
if (_managedMqttClient != null)
{
await _managedMqttClient.StopAsync();
_managedMqttClient.Dispose();
_managedMqttClient = null;
}
}
catch (Exception exception)
{
Trace.Text += exception + Environment.NewLine;
}
}
private void ClearLog(object sender, RoutedEventArgs e)
{
while (_traceMessages.Count > 0)
{
_traceMessages.TryDequeue(out _);
}
Trace.Text = string.Empty;
}
private async void Subscribe(object sender, RoutedEventArgs e)
{
try
{
var qos = MqttQualityOfServiceLevel.AtMostOnce;
if (SubscribeQoS1.IsChecked == true)
{
qos = MqttQualityOfServiceLevel.AtLeastOnce;
}
if (SubscribeQoS2.IsChecked == true)
{
qos = MqttQualityOfServiceLevel.ExactlyOnce;
}
var topicFilter = new MqttTopicFilter { Topic = SubscribeTopic.Text, QualityOfServiceLevel = qos };
if (_mqttClient != null)
{
await _mqttClient.SubscribeAsync(topicFilter);
}
if (_managedMqttClient != null)
{
await _managedMqttClient.SubscribeAsync(topicFilter);
}
}
catch (Exception exception)
{
Trace.Text += exception + Environment.NewLine;
}
}
private async void Unsubscribe(object sender, RoutedEventArgs e)
{
try
{
if (_mqttClient != null)
{
await _mqttClient.UnsubscribeAsync(SubscribeTopic.Text);
}
if (_managedMqttClient != null)
{
await _managedMqttClient.UnsubscribeAsync(SubscribeTopic.Text);
}
}
catch (Exception exception)
{
Trace.Text += exception + Environment.NewLine;
}
}
// This code is for the Wiki at GitHub!
// ReSharper disable once UnusedMember.Local
private async void StartServer(object sender, RoutedEventArgs e)
{
if (_mqttServer != null)
{
return;
}
JsonServerStorage storage = null;
if (ServerPersistRetainedMessages.IsChecked == true)
{
storage = new JsonServerStorage();
if (ServerClearRetainedMessages.IsChecked == true)
{
storage.Clear();
}
}
_mqttServer = new MqttFactory().CreateMqttServer();
var options = new MqttServerOptions();
options.DefaultEndpointOptions.Port = int.Parse(ServerPort.Text);
options.Storage = storage;
options.EnablePersistentSessions = ServerAllowPersistentSessions.IsChecked == true;
await _mqttServer.StartAsync(options);
}
private async void StopServer(object sender, RoutedEventArgs e)
{
if (_mqttServer == null)
{
return;
}
await _mqttServer.StopAsync();
_mqttServer = null;
}
private void ClearReceivedMessages(object sender, RoutedEventArgs e)
{
ReceivedMessages.Items.Clear();
}
private async void ExecuteRpc(object sender, RoutedEventArgs e)
{
var qos = MqttQualityOfServiceLevel.AtMostOnce;
if (RpcQoS1.IsChecked == true)
{
qos = MqttQualityOfServiceLevel.AtLeastOnce;
}
if (RpcQoS2.IsChecked == true)
{
qos = MqttQualityOfServiceLevel.ExactlyOnce;
}
var payload = Array.Empty<byte>();
if (RpcText.IsChecked == true)
{
payload = Encoding.UTF8.GetBytes(RpcPayload.Text);
}
if (RpcBase64.IsChecked == true)
{
payload = Convert.FromBase64String(RpcPayload.Text);
}
try
{
var rpcClient = new MqttRpcClient(_mqttClient, new MqttRpcClientOptions());
var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(5), RpcMethod.Text, payload, qos);
RpcResponses.Items.Add(RpcMethod.Text + " >>> " + Encoding.UTF8.GetString(response));
}
catch (MqttCommunicationTimedOutException)
{
RpcResponses.Items.Add(RpcMethod.Text + " >>> [TIMEOUT]");
}
catch (Exception exception)
{
RpcResponses.Items.Add(RpcMethod.Text + " >>> [EXCEPTION (" + exception.Message + ")]");
}
}
private void ClearRpcResponses(object sender, RoutedEventArgs e)
{
RpcResponses.Items.Clear();
}
private void ClearSessions(object sender, RoutedEventArgs e)
{
_sessions.Clear();
}
private void RefreshSessions(object sender, RoutedEventArgs e)
{
if (_mqttServer == null)
{
return;
}
var sessions = _mqttServer.GetClientStatusAsync().GetAwaiter().GetResult();
_sessions.Clear();
foreach (var session in sessions)
{
_sessions.Add(session);
}
ListViewSessions.DataContext = _sessions;
}
#region Wiki Code
#pragma warning disable IDE0051 // Remove unused private members
private async Task WikiCode()
#pragma warning restore IDE0051 // Remove unused private members
{
{
// Use a custom identifier for the trace messages.
var clientOptions = new MqttClientOptionsBuilder()
.Build();
}
{
// Create a new MQTT client.
var factory = new MqttFactory();
var client = factory.CreateMqttClient();
// Create TCP based options using the builder.
var options = new MqttClientOptionsBuilder()
.WithClientId("Client1")
.WithTcpServer("broker.hivemq.com")
.WithCredentials("bud", "%spencer%")
.WithTls()
.WithCleanSession()
.Build();
await client.ConnectAsync(options);
// Reconnecting
client.UseDisconnectedHandler(async e =>
{
Console.WriteLine("### DISCONNECTED FROM SERVER ###");
await Task.Delay(TimeSpan.FromSeconds(5));
try
{
await client.ConnectAsync(options);
}
catch
{
Console.WriteLine("### RECONNECTING FAILED ###");
}
});
// Consuming messages
client.UseApplicationMessageReceivedHandler(e =>
{
Console.WriteLine("### RECEIVED APPLICATION MESSAGE ###");
Console.WriteLine($"+ Topic = {e.ApplicationMessage.Topic}");
Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");
Console.WriteLine($"+ QoS = {e.ApplicationMessage.QualityOfServiceLevel}");
Console.WriteLine($"+ Retain = {e.ApplicationMessage.Retain}");
Console.WriteLine();
});
void Handler(MqttApplicationMessageReceivedEventArgs args)
{
//...
}
client.UseApplicationMessageReceivedHandler(e => Handler(e));
// Subscribe after connect
client.UseConnectedHandler(async e =>
{
Console.WriteLine("### CONNECTED WITH SERVER ###");
// Subscribe to a topic
await client.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("my/topic").Build());
Console.WriteLine("### SUBSCRIBED ###");
});
// Subscribe to a topic
await client.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("my/topic").Build());
// Unsubscribe from a topic
await client.UnsubscribeAsync("my/topic");
// Publish an application message
var applicationMessage = new MqttApplicationMessageBuilder()
.WithTopic("A/B/C")
.WithPayload("Hello World")
.WithAtLeastOnceQoS()
.Build();
await client.PublishAsync(applicationMessage);
}
{
{
// Use TCP connection.
var options = new MqttClientOptionsBuilder()
.WithTcpServer("broker.hivemq.com", 1883) // Port is optional
.Build();
}
{
// Use secure TCP connection.
var options = new MqttClientOptionsBuilder()
.WithTcpServer("broker.hivemq.com")
.WithTls()
.Build();
}
{
// Use WebSocket connection.
var options = new MqttClientOptionsBuilder()
.WithWebSocketServer("broker.hivemq.com:8000/mqtt")
.Build();
}
{
// Create TCP based options manually
var options = new MqttClientOptions
{
ClientId = "Client1",
Credentials = new MqttClientCredentials
{
Username = "bud",
Password = Encoding.UTF8.GetBytes("%spencer%")
},
ChannelOptions = new MqttClientTcpOptions
{
Server = "broker.hivemq.org",
TlsOptions = new MqttClientTlsOptions
{
UseTls = true
}
},
};
}
}
// ----------------------------------
{
var options = new MqttServerOptions
{
ConnectionValidator = new MqttServerConnectionValidatorDelegate(c =>
{
if (c.ClientId.Length < 10)
{
c.ReasonCode = MqttConnectReasonCode.ClientIdentifierNotValid;
return;
}
if (c.Username != "mySecretUser")
{
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
if (c.Password != "mySecretPassword")
{
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
c.ReasonCode = MqttConnectReasonCode.Success;
})
};
var factory = new MqttFactory();
var mqttServer = factory.CreateMqttServer();
await mqttServer.StartAsync(options);
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
await mqttServer.StopAsync();
}
// ----------------------------------
// For UWP apps:
MqttTcpChannel.CustomIgnorableServerCertificateErrorsResolver = o =>
{
if (o.Server == "server_with_revoked_cert")
{
return new[] { ChainValidationResult.Revoked };
}
return Array.Empty<ChainValidationResult>();
};
{
// Start a MQTT server.
var mqttServer = new MqttFactory().CreateMqttServer();
await mqttServer.StartAsync(new MqttServerOptions());
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
await mqttServer.StopAsync();
}
{
// Configure MQTT server.
var optionsBuilder = new MqttServerOptionsBuilder()
.WithConnectionBacklog(100)
.WithDefaultEndpointPort(1884);
var options = new MqttServerOptions
{
};
options.ConnectionValidator = new MqttServerConnectionValidatorDelegate(c =>
{
if (c.ClientId != "Highlander")
{
c.ReasonCode = MqttConnectReasonCode.ClientIdentifierNotValid;
return;
}
c.ReasonCode = MqttConnectReasonCode.Success;
});
var mqttServer = new MqttFactory().CreateMqttServer();
await mqttServer.StartAsync(optionsBuilder.Build());
}
{
// Setup client validator.
var options = new MqttServerOptions
{
ConnectionValidator = new MqttServerConnectionValidatorDelegate(c =>
{
if (c.ClientId.Length < 10)
{
c.ReasonCode = MqttConnectReasonCode.ClientIdentifierNotValid;
return;
}
if (c.Username != "mySecretUser")
{
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
if (c.Password != "mySecretPassword")
{
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
c.ReasonCode = MqttConnectReasonCode.Success;
})
};
}
{
// Create a new MQTT server.
var mqttServer = new MqttFactory().CreateMqttServer();
}
{
// Setup application message interceptor.
var options = new MqttServerOptionsBuilder()
.WithApplicationMessageInterceptor(context =>
{
if (context.ApplicationMessage.Topic == "my/custom/topic")
{
context.ApplicationMessage.Payload = Encoding.UTF8.GetBytes("The server injected payload.");
}
// It is also possible to read the payload and extend it. For example by adding a timestamp in a JSON document.
// This is useful when the IoT device has no own clock and the creation time of the message might be important.
})
.Build();
}
{
// Setup subscription interceptor.
var options = new MqttServerOptionsBuilder()
.WithSubscriptionInterceptor(context =>
{
if (context.TopicFilter.Topic.StartsWith("admin/foo/bar") && context.ClientId != "theAdmin")
{
context.AcceptSubscription = false;
}
if (context.TopicFilter.Topic.StartsWith("the/secret/stuff") && context.ClientId != "Imperator")
{
context.AcceptSubscription = false;
context.CloseConnection = true;
}
})
.Build();
}
{
// Setup and start a managed MQTT client.
var options = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
.WithClientOptions(new MqttClientOptionsBuilder()
.WithClientId("Client1")
.WithTcpServer("broker.hivemq.com")
.WithTls().Build())
.Build();
var mqttClient = new MqttFactory().CreateManagedMqttClient();
await mqttClient.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("my/topic").Build());
await mqttClient.StartAsync(options);
}
{
// Use a custom log ID for the logger.
var factory = new MqttFactory();
var client = factory.CreateMqttClient(new MqttNetLogger("MyCustomId"));
}
{
var client = new MqttFactory().CreateMqttClient();
var message = new MqttApplicationMessageBuilder()
.WithTopic("MyTopic")
.WithPayload("Hello World")
.WithExactlyOnceQoS()
.WithRetainFlag()
.Build();
await client.PublishAsync(message);
}
{
// Write all trace messages to the console window.
MqttNetGlobalLogger.LogMessagePublished += (s, e) =>
{
var trace = $">> [{e.LogMessage.Timestamp:O}] [{e.LogMessage.ThreadId}] [{e.LogMessage.Source}] [{e.LogMessage.Level}]: {e.LogMessage.Message}";
if (e.LogMessage.Exception != null)
{
trace += Environment.NewLine + e.LogMessage.Exception.ToString();
}
Console.WriteLine(trace);
};
}
}
#endregion
}
}
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" IgnorableNamespaces="uap mp uap3">
<Identity Name="4fa21172-9128-4e84-8a6d-74b9acde4d58" Publisher="CN=chris" Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="4fa21172-9128-4e84-8a6d-74b9acde4d58" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>MQTTnet.TestApp.UniversalWindows</DisplayName>
<PublisherDisplayName>test</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="MQTTnet.TestApp.UniversalWindows.App">
<uap:VisualElements DisplayName="MQTTnet Test App" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="Test application for MQTT based communication" BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
</uap:DefaultTile>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<Capability Name="internetClientServer" />
<Capability Name="privateNetworkClientServer" />
</Capabilities>
</Package>
@@ -1,14 +0,0 @@
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("MQTTnet.TestApp.UniversalWindows")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Christian Kratky")]
[assembly: AssemblyProduct("MQTTnet")]
[assembly: AssemblyCopyright("Copyright © Christian Kratky 2016-2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
@@ -1,31 +0,0 @@
<!--
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
developers. However, you can modify these parameters to modify the behavior of the .NET Native
optimizer.
Runtime Directives are documented at https://go.microsoft.com/fwlink/?LinkID=391919
To fully enable reflection for App1.MyClass and all of its public/private members
<Type Name="App1.MyClass" Dynamic="Required All"/>
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
<Namespace Name="DataClasses.ViewModels" Seralize="All" />
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All" />
<!-- Add your application specific runtime directives here. -->
</Application>
</Directives>