Browse Source

Refactoring

release/3.x.x
Christian 6 years ago
parent
commit
af8d1ec6be
13 changed files with 54 additions and 165 deletions
  1. +5
    -5
      Build/build.ps1
  2. +21
    -5
      Extensions/MQTTnet.Extensions.Rpc/MqttRpcClient.cs
  3. +3
    -3
      Frameworks/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs
  4. +0
    -72
      Frameworks/MQTTnet.AspnetCore/MqttWebSocketServerChannel.cs
  5. +1
    -1
      Frameworks/MQTTnet.NetStandard/Adapter/IMqttServerAdapter.cs
  6. +1
    -1
      Frameworks/MQTTnet.NetStandard/Adapter/MqttChannelAdapter.cs
  7. +8
    -9
      Frameworks/MQTTnet.NetStandard/Client/MqttPacketDispatcher.cs
  8. +1
    -1
      Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpServerAdapter.Uwp.cs
  9. +1
    -1
      Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpServerAdapter.cs
  10. +2
    -61
      Frameworks/MQTTnet.NetStandard/Implementations/MqttWebSocketChannel.cs
  11. +2
    -5
      Frameworks/MQTTnet.NetStandard/ManagedClient/ManagedMqttClient.cs
  12. +4
    -0
      Tests/MQTTnet.Core.Tests/TestMqttServerAdapter.cs
  13. +5
    -1
      Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs

+ 5
- 5
Build/build.ps1 View File

@@ -20,11 +20,11 @@ if ($path) {
&$msbuild ..\Frameworks\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" &$msbuild ..\Frameworks\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 # Build the RPC extension
&$msbuild ..\Extensions\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m
&$msbuild ..\Extensions\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m
&$msbuild ..\Extensions\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m
&$msbuild ..\Extensions\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m
&$msbuild ..\Extensions\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m
&$msbuild ..\Extensions\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 ..\Extensions\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 ..\Extensions\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 ..\Extensions\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 ..\Extensions\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"


Remove-Item .\NuGet -Force -Recurse -ErrorAction SilentlyContinue Remove-Item .\NuGet -Force -Recurse -ErrorAction SilentlyContinue




+ 21
- 5
Extensions/MQTTnet.Extensions.Rpc/MqttRpcClient.cs View File

@@ -4,6 +4,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Client; using MQTTnet.Client;
using MQTTnet.Exceptions;
using MQTTnet.Protocol; using MQTTnet.Protocol;


namespace MQTTnet.Extensions.Rpc namespace MQTTnet.Extensions.Rpc
@@ -63,10 +64,11 @@ namespace MQTTnet.Extensions.Rpc


await _mqttClient.SubscribeAsync(responseTopic, qualityOfServiceLevel).ConfigureAwait(false); await _mqttClient.SubscribeAsync(responseTopic, qualityOfServiceLevel).ConfigureAwait(false);
await _mqttClient.PublishAsync(requestMessage).ConfigureAwait(false); await _mqttClient.PublishAsync(requestMessage).ConfigureAwait(false);
using (var timeoutCts = new CancellationTokenSource(timeout)) using (var timeoutCts = new CancellationTokenSource(timeout))
using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token))
{ {
timeoutCts.Token.Register(() =>
linkedCts.Token.Register(() =>
{ {
if (!tcs.Task.IsCompleted && !tcs.Task.IsFaulted && !tcs.Task.IsCanceled) if (!tcs.Task.IsCompleted && !tcs.Task.IsFaulted && !tcs.Task.IsCanceled)
{ {
@@ -74,9 +76,23 @@ namespace MQTTnet.Extensions.Rpc
} }
}); });


var result = await tcs.Task.ConfigureAwait(false);
timeoutCts.Cancel(false);
return result;
try
{
var result = await tcs.Task.ConfigureAwait(false);
timeoutCts.Cancel(false);
return result;
}
catch (TaskCanceledException taskCanceledException)
{
if (timeoutCts.IsCancellationRequested && !cancellationToken.IsCancellationRequested)
{
throw new MqttCommunicationTimedOutException(taskCanceledException);
}
else
{
throw;
}
}
} }
} }
finally finally


+ 3
- 3
Frameworks/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs View File

@@ -3,12 +3,13 @@ using System.Net.WebSockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Adapter; using MQTTnet.Adapter;
using MQTTnet.Diagnostics; using MQTTnet.Diagnostics;
using MQTTnet.Implementations;
using MQTTnet.Serializer; using MQTTnet.Serializer;
using MQTTnet.Server; using MQTTnet.Server;


namespace MQTTnet.AspNetCore namespace MQTTnet.AspNetCore
{ {
public sealed class MqttWebSocketServerAdapter : IMqttServerAdapter, IDisposable
public class MqttWebSocketServerAdapter : IMqttServerAdapter
{ {
public event EventHandler<MqttServerAdapterClientAcceptedEventArgs> ClientAccepted; public event EventHandler<MqttServerAdapterClientAcceptedEventArgs> ClientAccepted;


@@ -26,8 +27,7 @@ namespace MQTTnet.AspNetCore
{ {
if (webSocket == null) throw new ArgumentNullException(nameof(webSocket)); if (webSocket == null) throw new ArgumentNullException(nameof(webSocket));


var channel = new MqttWebSocketServerChannel(webSocket);
var clientAdapter = new MqttChannelAdapter(channel, new MqttPacketSerializer(), new MqttNetLogger());
var clientAdapter = new MqttChannelAdapter(new MqttWebSocketChannel(webSocket), new MqttPacketSerializer(), new MqttNetLogger());


var eventArgs = new MqttServerAdapterClientAcceptedEventArgs(clientAdapter); var eventArgs = new MqttServerAdapterClientAcceptedEventArgs(clientAdapter);
ClientAccepted?.Invoke(this, eventArgs); ClientAccepted?.Invoke(this, eventArgs);


+ 0
- 72
Frameworks/MQTTnet.AspnetCore/MqttWebSocketServerChannel.cs View File

@@ -1,72 +0,0 @@
using System;
using System.IO;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Channel;
using MQTTnet.Implementations;

namespace MQTTnet.AspNetCore
{
public class MqttWebSocketServerChannel : IMqttChannel
{
private WebSocket _webSocket;
private readonly MqttWebSocketChannel _channel;

public MqttWebSocketServerChannel(WebSocket webSocket)
{
_webSocket = webSocket ?? throw new ArgumentNullException(nameof(webSocket));


_channel = new MqttWebSocketChannel(webSocket);
ReceiveStream = SendStream;
}

private Stream SendStream { get; set; }
private Stream ReceiveStream { get; set; }

public Task ConnectAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}

public async Task DisconnectAsync()
{
if (_webSocket == null)
{
return;
}

try
{
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).ConfigureAwait(false);
}
finally
{
Dispose();
}
}

public Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return ReceiveStream.ReadAsync(buffer, offset, count, cancellationToken);
}

public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return SendStream.WriteAsync(buffer, offset, count, cancellationToken);
}

public void Dispose()
{
SendStream?.Dispose();
ReceiveStream?.Dispose();

_webSocket?.Dispose();

SendStream = null;
ReceiveStream = null;
_webSocket = null;
}
}
}

+ 1
- 1
Frameworks/MQTTnet.NetStandard/Adapter/IMqttServerAdapter.cs View File

@@ -4,7 +4,7 @@ using MQTTnet.Server;


namespace MQTTnet.Adapter namespace MQTTnet.Adapter
{ {
public interface IMqttServerAdapter
public interface IMqttServerAdapter : IDisposable
{ {
event EventHandler<MqttServerAdapterClientAcceptedEventArgs> ClientAccepted; event EventHandler<MqttServerAdapterClientAcceptedEventArgs> ClientAccepted;




+ 1
- 1
Frameworks/MQTTnet.NetStandard/Adapter/MqttChannelAdapter.cs View File

@@ -134,7 +134,7 @@ namespace MQTTnet.Adapter
return new ReceivedMqttPacket(header, new MemoryStream(new byte[0], false)); return new ReceivedMqttPacket(header, new MemoryStream(new byte[0], false));
} }


var body = header.BodyLength <= ReadBufferSize ? new MemoryStream(header.BodyLength) : new MemoryStream();
var body = new MemoryStream(header.BodyLength);


var buffer = new byte[Math.Min(ReadBufferSize, header.BodyLength)]; var buffer = new byte[Math.Min(ReadBufferSize, header.BodyLength)];
while (body.Length < header.BodyLength) while (body.Length < header.BodyLength)


+ 8
- 9
Frameworks/MQTTnet.NetStandard/Client/MqttPacketDispatcher.cs View File

@@ -10,7 +10,7 @@ namespace MQTTnet.Client
{ {
public class MqttPacketDispatcher public class MqttPacketDispatcher
{ {
private readonly ConcurrentDictionary<Tuple<ushort?, Type>, TaskCompletionSource<MqttBasePacket>> _awaiters = new ConcurrentDictionary<Tuple<ushort?, Type>, TaskCompletionSource<MqttBasePacket>>();
private readonly ConcurrentDictionary<Tuple<ushort, Type>, TaskCompletionSource<MqttBasePacket>> _awaiters = new ConcurrentDictionary<Tuple<ushort, Type>, TaskCompletionSource<MqttBasePacket>>();
private readonly IMqttNetLogger _logger; private readonly IMqttNetLogger _logger;


public MqttPacketDispatcher(IMqttNetLogger logger) public MqttPacketDispatcher(IMqttNetLogger logger)
@@ -40,16 +40,15 @@ namespace MQTTnet.Client
{ {
if (packet == null) throw new ArgumentNullException(nameof(packet)); if (packet == null) throw new ArgumentNullException(nameof(packet));


ushort? identifier = 0;
if (packet is IMqttPacketWithIdentifier packetWithIdentifier)
ushort identifier = 0;
if (packet is IMqttPacketWithIdentifier packetWithIdentifier && packetWithIdentifier.PacketIdentifier.HasValue)
{ {
identifier = packetWithIdentifier.PacketIdentifier;
identifier = packetWithIdentifier.PacketIdentifier.Value;
} }


var type = packet.GetType(); var type = packet.GetType();
var key = new Tuple<ushort?, Type>(identifier, type);


var key = new Tuple<ushort, Type>(identifier, type);
if (_awaiters.TryRemove(key, out var tcs)) if (_awaiters.TryRemove(key, out var tcs))
{ {
tcs.TrySetResult(packet); tcs.TrySetResult(packet);
@@ -73,7 +72,7 @@ namespace MQTTnet.Client
identifier = 0; identifier = 0;
} }


var dictionaryKey = new Tuple<ushort?, Type>(identifier, responseType);
var dictionaryKey = new Tuple<ushort, Type>(identifier ?? 0, responseType);
if (!_awaiters.TryAdd(dictionaryKey, tcs)) if (!_awaiters.TryAdd(dictionaryKey, tcs))
{ {
throw new InvalidOperationException($"The packet dispatcher already has an awaiter for packet of type '{responseType}' with identifier {identifier}."); throw new InvalidOperationException($"The packet dispatcher already has an awaiter for packet of type '{responseType}' with identifier {identifier}.");
@@ -89,7 +88,7 @@ namespace MQTTnet.Client
identifier = 0; identifier = 0;
} }


var dictionaryKey = new Tuple<ushort?, Type>(identifier, responseType);
var dictionaryKey = new Tuple<ushort, Type>(identifier ?? 0, responseType);
_awaiters.TryRemove(dictionaryKey, out var _); _awaiters.TryRemove(dictionaryKey, out var _);
} }
} }

+ 1
- 1
Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpServerAdapter.Uwp.cs View File

@@ -9,7 +9,7 @@ using MQTTnet.Server;


namespace MQTTnet.Implementations namespace MQTTnet.Implementations
{ {
public class MqttTcpServerAdapter : IMqttServerAdapter, IDisposable
public class MqttTcpServerAdapter : IMqttServerAdapter
{ {
private readonly IMqttNetLogger _logger; private readonly IMqttNetLogger _logger;
private StreamSocketListener _defaultEndpointSocket; private StreamSocketListener _defaultEndpointSocket;


+ 1
- 1
Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpServerAdapter.cs View File

@@ -14,7 +14,7 @@ using MQTTnet.Server;


namespace MQTTnet.Implementations namespace MQTTnet.Implementations
{ {
public class MqttTcpServerAdapter : IMqttServerAdapter, IDisposable
public class MqttTcpServerAdapter : IMqttServerAdapter
{ {
private readonly IMqttNetLogger _logger; private readonly IMqttNetLogger _logger;




+ 2
- 61
Frameworks/MQTTnet.NetStandard/Implementations/MqttWebSocketChannel.cs View File

@@ -5,25 +5,18 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Channel; using MQTTnet.Channel;
using MQTTnet.Client; using MQTTnet.Client;
using MQTTnet.Exceptions;


namespace MQTTnet.Implementations namespace MQTTnet.Implementations
{ {
public sealed class MqttWebSocketChannel : IMqttChannel public sealed class MqttWebSocketChannel : IMqttChannel
{ {
private readonly MqttClientWebSocketOptions _options; private readonly MqttClientWebSocketOptions _options;
private readonly byte[] _chunkBuffer;

private int _chunkBufferLength;
private int _chunkBufferOffset;


private WebSocket _webSocket; private WebSocket _webSocket;


public MqttWebSocketChannel(MqttClientWebSocketOptions options) public MqttWebSocketChannel(MqttClientWebSocketOptions options)
{ {
_options = options ?? throw new ArgumentNullException(nameof(options)); _options = options ?? throw new ArgumentNullException(nameof(options));

_chunkBuffer = new byte[options.BufferSize];
} }


public MqttWebSocketChannel(WebSocket webSocket) public MqttWebSocketChannel(WebSocket webSocket)
@@ -99,32 +92,8 @@ namespace MQTTnet.Implementations


public async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) public async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{ {
var bytesRead = 0;

while (_webSocket.State == WebSocketState.Open)
{
await EnsureFilledChunkBufferAsync(cancellationToken).ConfigureAwait(false);
if (_chunkBufferLength == 0)
{
return 0;
}

while (count > 0 && _chunkBufferOffset < _chunkBufferLength)
{
buffer[offset] = _chunkBuffer[_chunkBufferOffset];
_chunkBufferOffset++;
count--;
bytesRead++;
offset++;
}

if (count == 0)
{
return bytesRead;
}
}
return bytesRead;
var response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken).ConfigureAwait(false);
return response.Count;
} }


public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
@@ -146,33 +115,5 @@ namespace MQTTnet.Implementations
_webSocket = null; _webSocket = null;
} }
} }

private async Task EnsureFilledChunkBufferAsync(CancellationToken cancellationToken)
{
if (_chunkBufferOffset < _chunkBufferLength)
{
return;
}

if (_webSocket.State == WebSocketState.Closed)
{
throw new MqttCommunicationException("WebSocket connection closed.");
}

var response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(_chunkBuffer, 0, _chunkBuffer.Length), cancellationToken).ConfigureAwait(false);
_chunkBufferLength = response.Count;
_chunkBufferOffset = 0;

if (response.MessageType == WebSocketMessageType.Close)
{
throw new MqttCommunicationException("The WebSocket server closed the connection.");
//await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken).ConfigureAwait(false);
}

if (response.MessageType == WebSocketMessageType.Text)
{
throw new MqttProtocolViolationException("WebSocket channel received TEXT message.");
}
}
} }
} }

+ 2
- 5
Frameworks/MQTTnet.NetStandard/ManagedClient/ManagedMqttClient.cs View File

@@ -71,7 +71,7 @@ namespace MQTTnet.ManagedClient
_connectionCancellationToken = new CancellationTokenSource(); _connectionCancellationToken = new CancellationTokenSource();


#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Run(async () => await MaintainConnectionAsync(_connectionCancellationToken.Token).ConfigureAwait(false), _connectionCancellationToken.Token).ConfigureAwait(false);
Task.Run(() => MaintainConnectionAsync(_connectionCancellationToken.Token), _connectionCancellationToken.Token);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed


_logger.Info<ManagedMqttClient>("Started"); _logger.Info<ManagedMqttClient>("Started");
@@ -190,10 +190,7 @@ namespace MQTTnet.ManagedClient
if (connectionState == ReconnectionResult.Reconnected || _subscriptionsNotPushed) if (connectionState == ReconnectionResult.Reconnected || _subscriptionsNotPushed)
{ {
await SynchronizeSubscriptionsAsync().ConfigureAwait(false); await SynchronizeSubscriptionsAsync().ConfigureAwait(false);

StartPublishing(); StartPublishing();


return; return;
} }


@@ -375,7 +372,7 @@ namespace MQTTnet.ManagedClient
_publishingCancellationToken = cts; _publishingCancellationToken = cts;


#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Run(async () => await PublishQueuedMessagesAsync(cts.Token).ConfigureAwait(false), cts.Token).ConfigureAwait(false);
Task.Run(() => PublishQueuedMessagesAsync(cts.Token), cts.Token);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
} }




+ 4
- 0
Tests/MQTTnet.Core.Tests/TestMqttServerAdapter.cs View File

@@ -71,5 +71,9 @@ namespace MQTTnet.Core.Tests
{ {
return Task.FromResult(0); return Task.FromResult(0);
} }

public void Dispose()
{
}
} }
} }

+ 5
- 1
Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs View File

@@ -354,13 +354,17 @@ namespace MQTTnet.TestApp.UniversalWindows
{ {
var rpcClient = new MqttRpcClient(_mqttClient); var rpcClient = new MqttRpcClient(_mqttClient);
var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(5), RpcMethod.Text, payload, qos); var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(5), RpcMethod.Text, payload, qos);
RpcResponses.Items.Add(RpcMethod.Text + " >>> " + Encoding.UTF8.GetString(response)); RpcResponses.Items.Add(RpcMethod.Text + " >>> " + Encoding.UTF8.GetString(response));
} }
catch (MqttCommunicationTimedOutException) catch (MqttCommunicationTimedOutException)
{ {
RpcResponses.Items.Add(RpcMethod.Text + " >>> [TIMEOUT]"); RpcResponses.Items.Add(RpcMethod.Text + " >>> [TIMEOUT]");
} }
catch (Exception exception)
{
RpcResponses.Items.Add(RpcMethod.Text + " >>> [EXCEPTION (" + exception.Message + ")]");
}
} }


private void ClearRpcResponses(object sender, RoutedEventArgs e) private void ClearRpcResponses(object sender, RoutedEventArgs e)


Loading…
Cancel
Save