Просмотр исходного кода

Update docs, fix managed client connection issue

release/3.x.x
Christian Kratky 7 лет назад
Родитель
Сommit
69781d822a
8 измененных файлов: 140 добавлений и 61 удалений
  1. +8
    -3
      Build/MQTTnet.nuspec
  2. +14
    -1
      Frameworks/MQTTnet.NetStandard/Adapter/MqttChannelAdapter.cs
  3. +46
    -27
      Frameworks/MQTTnet.NetStandard/ManagedClient/ManagedMqttClient.cs
  4. +6
    -1
      Frameworks/MQTTnet.NetStandard/Server/ConnectedMqttClient.cs
  5. +14
    -5
      Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs
  6. +27
    -20
      Tests/MQTTnet.TestApp.NetCore/MqttNetConsoleLogger.cs
  7. +20
    -1
      Tests/MQTTnet.TestApp.NetCore/ServerTest.cs
  8. +5
    -3
      Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs

+ 8
- 3
Build/MQTTnet.nuspec Просмотреть файл

@@ -10,9 +10,14 @@
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker).</description>
<releaseNotes>* Merged projects.
* Added a strong name for the assembly.

<releaseNotes>* [Core] Merged projects (BREAKING CHANGE! But only namespace changes).
* [Core] Added a strong name for the assembly.
* [Core] Performance optimizations.
* [Core] Fixed a logging issue when dealing with IOExceptions.
* [Client] Fixed an issue in _ManagedClient_ which can cause the client to stop when publishing subscriptions.
* [Server] The application message interceptor can now delete any received application message.
* [Server] Added a ConnectionValidator context to align with other APIs.
* [Server] Added an interface for the _MqttServerOptions_.
</releaseNotes>
<copyright>Copyright Christian Kratky 2016-2017</copyright>
<tags>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</tags>


+ 14
- 1
Frameworks/MQTTnet.NetStandard/Adapter/MqttChannelAdapter.cs Просмотреть файл

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@@ -171,13 +172,25 @@ namespace MQTTnet.Adapter
}
catch (COMException comException)
{
if ((uint)comException.HResult == ErrorOperationAborted)
if ((uint) comException.HResult == ErrorOperationAborted)
{
throw new OperationCanceledException();
}

throw new MqttCommunicationException(comException);
}
catch (IOException exception)
{
if (exception.InnerException is SocketException socketException)
{
if (socketException.SocketErrorCode == SocketError.ConnectionAborted)
{
throw new OperationCanceledException();
}
}

throw new MqttCommunicationException(exception);
}
catch (Exception exception)
{
throw new MqttCommunicationException(exception);


+ 46
- 27
Frameworks/MQTTnet.NetStandard/ManagedClient/ManagedMqttClient.cs Просмотреть файл

@@ -142,33 +142,53 @@ namespace MQTTnet.ManagedClient
{
while (!cancellationToken.IsCancellationRequested)
{
var connectionState = await ReconnectIfRequiredAsync().ConfigureAwait(false);
if (connectionState == ReconnectionResult.NotConnected)
{
_publishingCancellationToken?.Cancel(false);
_publishingCancellationToken = null;
await TryMaintainConnectionAsync(cancellationToken);
}
}
catch (OperationCanceledException)
{
}
catch (Exception exception)
{
_logger.Error<ManagedMqttClient>(exception, "Unhandled exception while maintaining connection.");
}
finally
{
await _mqttClient.DisconnectAsync().ConfigureAwait(false);
_logger.Info<ManagedMqttClient>("Stopped");
}
}

await Task.Delay(_options.AutoReconnectDelay, cancellationToken).ConfigureAwait(false);
continue;
}
private async Task TryMaintainConnectionAsync(CancellationToken cancellationToken)
{
try
{
var connectionState = await ReconnectIfRequiredAsync().ConfigureAwait(false);
if (connectionState == ReconnectionResult.NotConnected)
{
_publishingCancellationToken?.Cancel(false);
_publishingCancellationToken = null;

if (connectionState == ReconnectionResult.Reconnected || _subscriptionsNotPushed)
{
await PushSubscriptionsAsync();
await Task.Delay(_options.AutoReconnectDelay, cancellationToken).ConfigureAwait(false);
return;
}

if (connectionState == ReconnectionResult.Reconnected || _subscriptionsNotPushed)
{
await PushSubscriptionsAsync().ConfigureAwait(false);

_publishingCancellationToken = new CancellationTokenSource();
_publishingCancellationToken = new CancellationTokenSource();

#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(_publishingCancellationToken.Token), _publishingCancellationToken.Token).ConfigureAwait(false);
Task.Run(async () => await PublishQueuedMessagesAsync(_publishingCancellationToken.Token).ConfigureAwait(false), _publishingCancellationToken.Token).ConfigureAwait(false);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed

continue;
}
return;
}

if (connectionState == ReconnectionResult.StillConnected)
{
await Task.Delay(TimeSpan.FromSeconds(1), _connectionCancellationToken.Token).ConfigureAwait(false);
}
if (connectionState == ReconnectionResult.StillConnected)
{
await Task.Delay(TimeSpan.FromSeconds(1), _connectionCancellationToken.Token).ConfigureAwait(false);
}
}
catch (OperationCanceledException)
@@ -182,11 +202,6 @@ namespace MQTTnet.ManagedClient
{
_logger.Error<ManagedMqttClient>(exception, "Unhandled exception while maintaining connection.");
}
finally
{
await _mqttClient.DisconnectAsync().ConfigureAwait(false);
_logger.Info<ManagedMqttClient>("Stopped");
}
}

private async Task PublishQueuedMessagesAsync(CancellationToken cancellationToken)
@@ -206,16 +221,19 @@ namespace MQTTnet.ManagedClient
continue;
}

await TryPublishQueuedMessageAsync(message).ConfigureAwait(false);
await _storageManager.RemoveAsync(message).ConfigureAwait(false);
await TryPublishQueuedMessageAsync(message).ConfigureAwait(false);
}
}
catch (OperationCanceledException)
{
}
catch (Exception exception)
{
_logger.Error<ManagedMqttClient>(exception, "Unhandled exception while publishing queued application messages.");
}
finally
{
_logger.Info<ManagedMqttClient>("Stopped publishing messages");
_logger.Trace<ManagedMqttClient>("Stopped publishing messages.");
}
}

@@ -224,6 +242,7 @@ namespace MQTTnet.ManagedClient
try
{
await _mqttClient.PublishAsync(message).ConfigureAwait(false);
await _storageManager.RemoveAsync(message).ConfigureAwait(false);
}
catch (MqttCommunicationException exception)
{


+ 6
- 1
Frameworks/MQTTnet.NetStandard/Server/ConnectedMqttClient.cs Просмотреть файл

@@ -1,4 +1,5 @@
using MQTTnet.Serializer;
using System;
using MQTTnet.Serializer;

namespace MQTTnet.Server
{
@@ -7,5 +8,9 @@ namespace MQTTnet.Server
public string ClientId { get; set; }

public MqttProtocolVersion ProtocolVersion { get; set; }

public TimeSpan LastPacketReceivedDuration { get; set; }

public TimeSpan LastNonKeepAlivePacketReceivedDuration{ get; set; }
}
}

+ 14
- 5
Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs Просмотреть файл

@@ -120,6 +120,7 @@ namespace MQTTnet.Server
await _sessionsSemaphore.WaitAsync().ConfigureAwait(false);
try
{
var now = DateTime.UtcNow;
return _sessions.Where(s => s.Value.IsConnected).Select(s => new ConnectedMqttClient
{
ClientId = s.Value.ClientId,
@@ -136,13 +137,21 @@ namespace MQTTnet.Server
{
try
{
var interceptorContext = new MqttApplicationMessageInterceptorContext
if (_options.ApplicationMessageInterceptor != null)
{
ApplicationMessage = applicationMessage
};
var interceptorContext = new MqttApplicationMessageInterceptorContext
{
ApplicationMessage = applicationMessage
};

_options.ApplicationMessageInterceptor(interceptorContext);
applicationMessage = interceptorContext.ApplicationMessage;
}

_options.ApplicationMessageInterceptor?.Invoke(interceptorContext);
applicationMessage = interceptorContext.ApplicationMessage;
if (applicationMessage == null)
{
return;
}

if (applicationMessage.Retain)
{


+ 27
- 20
Tests/MQTTnet.TestApp.NetCore/MqttNetConsoleLogger.cs Просмотреть файл

@@ -14,6 +14,17 @@ namespace MQTTnet.TestApp.NetCore
MqttNetGlobalLogger.LogMessagePublished += PrintToConsole;
}

public static void PrintToConsole(string message, ConsoleColor color)
{
lock (Lock)
{
var backupColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.Write(message);
Console.ForegroundColor = backupColor;
}
}

private static void PrintToConsole(object sender, MqttNetLogMessagePublishedEventArgs e)
{
var output = new StringBuilder();
@@ -23,28 +34,24 @@ namespace MQTTnet.TestApp.NetCore
output.AppendLine(e.TraceMessage.Exception.ToString());
}

lock (Lock)
var color = ConsoleColor.Red;
switch (e.TraceMessage.Level)
{
var backupColor = Console.ForegroundColor;
switch (e.TraceMessage.Level)
{
case MqttNetLogLevel.Error:
Console.ForegroundColor = ConsoleColor.Red;
break;
case MqttNetLogLevel.Warning:
Console.ForegroundColor = ConsoleColor.Yellow;
break;
case MqttNetLogLevel.Info:
Console.ForegroundColor = ConsoleColor.Green;
break;
case MqttNetLogLevel.Verbose:
Console.ForegroundColor = ConsoleColor.Gray;
break;
}

Console.Write(output);
Console.ForegroundColor = backupColor;
case MqttNetLogLevel.Error:
color = ConsoleColor.Red;
break;
case MqttNetLogLevel.Warning:
color = ConsoleColor.Yellow;
break;
case MqttNetLogLevel.Info:
color = ConsoleColor.Green;
break;
case MqttNetLogLevel.Verbose:
color = ConsoleColor.Gray;
break;
}

PrintToConsole(output.ToString(), color);
}
}
}

+ 20
- 1
Tests/MQTTnet.TestApp.NetCore/ServerTest.cs Просмотреть файл

@@ -1,9 +1,9 @@
using System;
using System.Text;
using System.Threading.Tasks;
using MQTTnet.Diagnostics;
using MQTTnet.Protocol;
using MQTTnet.Server;
using Newtonsoft.Json.Linq;

namespace MQTTnet.TestApp.NetCore
{
@@ -63,6 +63,25 @@ namespace MQTTnet.TestApp.NetCore
//options.TlsEndpointOptions.IsEnabled = false;

var mqttServer = new MqttFactory().CreateMqttServer();

mqttServer.ApplicationMessageReceived += (s, e) =>
{
MqttNetConsoleLogger.PrintToConsole(
$"'{e.ClientId}' reported '{e.ApplicationMessage.Topic}' > '{Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}'",
ConsoleColor.Magenta);
};

options.ApplicationMessageInterceptor = c =>
{
var content = JObject.Parse(Encoding.UTF8.GetString(c.ApplicationMessage.Payload));
var timestampProperty = content.Property("timestamp");
if (timestampProperty != null && timestampProperty.Value.Type == JTokenType.Null)
{
timestampProperty.Value = DateTime.Now.ToString("O");
c.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(content.ToString());
}
};

mqttServer.ClientDisconnected += (s, e) =>
{
Console.Write("Client disconnected event fired.");


+ 5
- 3
Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs Просмотреть файл

@@ -407,12 +407,14 @@ namespace MQTTnet.TestApp.UniversalWindows

{
// Configure MQTT server.
var optionsBuilder = new MqttServerOptionsBuilder()
.WithConnectionBacklog(100)
.WithDefaultEndpointPort(1884);

var options = new MqttServerOptions
{
ConnectionBacklog = 100
};

options.DefaultEndpointOptions.Port = 1884;
options.ConnectionValidator = c =>
{
if (c.ClientId != "Highlander")
@@ -425,7 +427,7 @@ namespace MQTTnet.TestApp.UniversalWindows
};

var mqttServer = new MqttFactory().CreateMqttServer();
await mqttServer.StartAsync(options);
await mqttServer.StartAsync(optionsBuilder.Build());
}

{


Загрузка…
Отмена
Сохранить