@@ -0,0 +1,5 @@ | |||||
[*.cs] | |||||
# CA1031: Do not catch general exception types | |||||
dotnet_diagnostic.CA1031.severity = none |
@@ -15,6 +15,7 @@ | |||||
* [Core] Renamed some topic filter relevant classes (BREAKING CHANGE!). | * [Core] Renamed some topic filter relevant classes (BREAKING CHANGE!). | ||||
* [Core] Improved task management for UWP connections (thanks to @xgstation). | * [Core] Improved task management for UWP connections (thanks to @xgstation). | ||||
* [Core] Fixed broken logger which decreases overall performance. | * [Core] Fixed broken logger which decreases overall performance. | ||||
* [Core] Fixed issue in closed socket detection (fixes high CPU load issue). | |||||
* [Client] Added method to trigger PING/PONG manually (connection check etc.). | * [Client] Added method to trigger PING/PONG manually (connection check etc.). | ||||
* [Client] Added support for certificate validation callback when using Web Sockets (requires netstandard2.1+). | * [Client] Added support for certificate validation callback when using Web Sockets (requires netstandard2.1+). | ||||
* [Client] Fixed a memory leak when web socket based connections trying to reconnect with an offline server. | * [Client] Fixed a memory leak when web socket based connections trying to reconnect with an offline server. | ||||
@@ -27,6 +27,7 @@ EndProject | |||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B3F60ECB-45BA-4C66-8903-8BB89CA67998}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B3F60ECB-45BA-4C66-8903-8BB89CA67998}" | ||||
ProjectSection(SolutionItems) = preProject | ProjectSection(SolutionItems) = preProject | ||||
.bettercodehub.yml = .bettercodehub.yml | .bettercodehub.yml = .bettercodehub.yml | ||||
.editorconfig = .editorconfig | |||||
appveyor.yml = appveyor.yml | appveyor.yml = appveyor.yml | ||||
LICENSE = LICENSE | LICENSE = LICENSE | ||||
README.md = README.md | README.md = README.md | ||||
@@ -14,7 +14,7 @@ | |||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies> | <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies> | ||||
<NugetTargetMoniker>UAP,Version=v10.0</NugetTargetMoniker> | <NugetTargetMoniker>UAP,Version=v10.0</NugetTargetMoniker> | ||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> | <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> | ||||
<TargetPlatformVersion>10.0.17134.0</TargetPlatformVersion> | |||||
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion> | |||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion> | <TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion> | ||||
<TargetFrameworkIdentifier>.NETCore</TargetFrameworkIdentifier> | <TargetFrameworkIdentifier>.NETCore</TargetFrameworkIdentifier> | ||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion> | <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> | ||||
@@ -14,7 +14,7 @@ | |||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies> | <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies> | ||||
<NugetTargetMoniker>UAP,Version=v10.0</NugetTargetMoniker> | <NugetTargetMoniker>UAP,Version=v10.0</NugetTargetMoniker> | ||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> | <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> | ||||
<TargetPlatformVersion>10.0.17134.0</TargetPlatformVersion> | |||||
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion> | |||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion> | <TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion> | ||||
<TargetFrameworkIdentifier>.NETCore</TargetFrameworkIdentifier> | <TargetFrameworkIdentifier>.NETCore</TargetFrameworkIdentifier> | ||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion> | <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> | ||||
@@ -14,7 +14,7 @@ | |||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies> | <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies> | ||||
<NugetTargetMoniker>UAP,Version=v10.0</NugetTargetMoniker> | <NugetTargetMoniker>UAP,Version=v10.0</NugetTargetMoniker> | ||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> | <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> | ||||
<TargetPlatformVersion>10.0.17134.0</TargetPlatformVersion> | |||||
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion> | |||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion> | <TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion> | ||||
<TargetFrameworkIdentifier>.NETCore</TargetFrameworkIdentifier> | <TargetFrameworkIdentifier>.NETCore</TargetFrameworkIdentifier> | ||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion> | <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> | ||||
@@ -16,8 +16,8 @@ namespace MQTTnet.Adapter | |||||
{ | { | ||||
public sealed class MqttChannelAdapter : Disposable, IMqttChannelAdapter | public sealed class MqttChannelAdapter : Disposable, IMqttChannelAdapter | ||||
{ | { | ||||
const uint ErrorOperationAborted = 0x800703E3; | |||||
const int ReadBufferSize = 4096; // TODO: Move buffer size to config | |||||
const uint _errorOperationAborted = 0x800703E3; | |||||
const int _readBufferSize = 4096; // TODO: Move buffer size to config | |||||
readonly IMqttNetScopedLogger _logger; | readonly IMqttNetScopedLogger _logger; | ||||
readonly IMqttChannel _channel; | readonly IMqttChannel _channel; | ||||
@@ -245,7 +245,7 @@ namespace MQTTnet.Adapter | |||||
var body = new byte[fixedHeader.RemainingLength]; | var body = new byte[fixedHeader.RemainingLength]; | ||||
var bodyOffset = 0; | var bodyOffset = 0; | ||||
var chunkSize = Math.Min(ReadBufferSize, fixedHeader.RemainingLength); | |||||
var chunkSize = Math.Min(_readBufferSize, fixedHeader.RemainingLength); | |||||
do | do | ||||
{ | { | ||||
@@ -304,7 +304,7 @@ namespace MQTTnet.Adapter | |||||
if (exception is COMException comException) | if (exception is COMException comException) | ||||
{ | { | ||||
if ((uint)comException.HResult == ErrorOperationAborted) | |||||
if ((uint)comException.HResult == _errorOperationAborted) | |||||
{ | { | ||||
throw new OperationCanceledException(); | throw new OperationCanceledException(); | ||||
} | } | ||||
@@ -277,7 +277,10 @@ namespace MQTTnet.Client.Options | |||||
#else | #else | ||||
Certificates = _tlsParameters.Certificates?.ToList(), | Certificates = _tlsParameters.Certificates?.ToList(), | ||||
#endif | #endif | ||||
#pragma warning disable CS0618 // Type or member is obsolete | |||||
CertificateValidationCallback = _tlsParameters.CertificateValidationCallback, | CertificateValidationCallback = _tlsParameters.CertificateValidationCallback, | ||||
#pragma warning restore CS0618 // Type or member is obsolete | |||||
CertificateValidationHandler = _tlsParameters.CertificateValidationHandler, | CertificateValidationHandler = _tlsParameters.CertificateValidationHandler, | ||||
IgnoreCertificateChainErrors = _tlsParameters.IgnoreCertificateChainErrors, | IgnoreCertificateChainErrors = _tlsParameters.IgnoreCertificateChainErrors, | ||||
IgnoreCertificateRevocationErrors = _tlsParameters.IgnoreCertificateRevocationErrors | IgnoreCertificateRevocationErrors = _tlsParameters.IgnoreCertificateRevocationErrors | ||||
@@ -5,8 +5,7 @@ namespace MQTTnet.Diagnostics | |||||
public class MqttNetLogger : IMqttNetLogger | public class MqttNetLogger : IMqttNetLogger | ||||
{ | { | ||||
readonly string _logId; | readonly string _logId; | ||||
readonly string _source; | |||||
public MqttNetLogger() | public MqttNetLogger() | ||||
{ | { | ||||
} | } | ||||
@@ -37,23 +36,20 @@ namespace MQTTnet.Diagnostics | |||||
return; | return; | ||||
} | } | ||||
if (parameters?.Length > 0) | |||||
try | |||||
{ | |||||
message = string.Format(message ?? string.Empty, parameters); | |||||
} | |||||
catch (FormatException) | |||||
{ | { | ||||
try | |||||
{ | |||||
message = string.Format(message, parameters); | |||||
} | |||||
catch | |||||
{ | |||||
message = "MESSAGE FORMAT INVALID: " + message; | |||||
} | |||||
message = "MESSAGE FORMAT INVALID: " + message; | |||||
} | } | ||||
var logMessage = new MqttNetLogMessage | var logMessage = new MqttNetLogMessage | ||||
{ | { | ||||
LogId = _logId, | LogId = _logId, | ||||
Timestamp = DateTime.UtcNow, | Timestamp = DateTime.UtcNow, | ||||
Source = _source, | |||||
Source = source, | |||||
ThreadId = Environment.CurrentManagedThreadId, | ThreadId = Environment.CurrentManagedThreadId, | ||||
Level = level, | Level = level, | ||||
Message = message, | Message = message, | ||||
@@ -85,7 +85,12 @@ namespace MQTTnet.Implementations | |||||
} | } | ||||
catch | catch | ||||
{ | { | ||||
#if NETSTANDARD2_1 | |||||
await sslStream.DisposeAsync().ConfigureAwait(false); | |||||
#else | |||||
sslStream.Dispose(); | sslStream.Dispose(); | ||||
#endif | |||||
throw; | throw; | ||||
} | } | ||||
@@ -127,7 +132,8 @@ namespace MQTTnet.Implementations | |||||
} | } | ||||
catch (ObjectDisposedException) | catch (ObjectDisposedException) | ||||
{ | { | ||||
return -1; | |||||
// Indicate a graceful socket close. | |||||
return 0; | |||||
} | } | ||||
catch (IOException exception) | catch (IOException exception) | ||||
{ | { | ||||
@@ -190,15 +196,17 @@ namespace MQTTnet.Implementations | |||||
bool InternalUserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) | bool InternalUserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) | ||||
{ | { | ||||
#region OBSOLETE | |||||
#region OBSOLETE | |||||
#pragma warning disable CS0618 // Type or member is obsolete | |||||
var certificateValidationCallback = _options?.TlsOptions?.CertificateValidationCallback; | var certificateValidationCallback = _options?.TlsOptions?.CertificateValidationCallback; | ||||
#pragma warning restore CS0618 // Type or member is obsolete | |||||
if (certificateValidationCallback != null) | if (certificateValidationCallback != null) | ||||
{ | { | ||||
return certificateValidationCallback(x509Certificate, chain, sslPolicyErrors, _clientOptions); | return certificateValidationCallback(x509Certificate, chain, sslPolicyErrors, _clientOptions); | ||||
} | } | ||||
#endregion | |||||
#endregion | |||||
var certificateValidationHandler = _options?.TlsOptions?.CertificateValidationHandler; | var certificateValidationHandler = _options?.TlsOptions?.CertificateValidationHandler; | ||||
if (certificateValidationHandler != null) | if (certificateValidationHandler != null) | ||||
@@ -20,8 +20,8 @@ | |||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies> | <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies> | ||||
<NugetTargetMoniker>UAP,Version=v10.0</NugetTargetMoniker> | <NugetTargetMoniker>UAP,Version=v10.0</NugetTargetMoniker> | ||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> | <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> | ||||
<TargetPlatformVersion>10.0.17134.0</TargetPlatformVersion> | |||||
<TargetPlatformMinVersion>10.0.10586.212</TargetPlatformMinVersion> | |||||
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion> | |||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion> | |||||
<TargetFrameworkIdentifier>.NETCore</TargetFrameworkIdentifier> | <TargetFrameworkIdentifier>.NETCore</TargetFrameworkIdentifier> | ||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion> | <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> | ||||
<DefineConstants>$(DefineConstants);WINDOWS_UWP</DefineConstants> | <DefineConstants>$(DefineConstants);WINDOWS_UWP</DefineConstants> | ||||
@@ -13,8 +13,8 @@ namespace MQTTnet.Benchmarks.Configurations | |||||
{ | { | ||||
public AllowNonOptimized() | public AllowNonOptimized() | ||||
{ | { | ||||
Add(JitOptimizationsValidator.DontFailOnError); // ALLOW NON-OPTIMIZED DLLS | |||||
Add(Job.InProcess); | |||||
AddValidator(JitOptimizationsValidator.DontFailOnError); // ALLOW NON-OPTIMIZED DLLS | |||||
AddJob(Job.InProcess); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -7,9 +7,9 @@ namespace MQTTnet.Benchmarks.Configurations | |||||
{ | { | ||||
public BaseConfig() | public BaseConfig() | ||||
{ | { | ||||
Add(DefaultConfig.Instance.GetLoggers().ToArray()); // manual config has no loggers by default | |||||
Add(DefaultConfig.Instance.GetExporters().ToArray()); // manual config has no exporters by default | |||||
Add(DefaultConfig.Instance.GetColumnProviders().ToArray()); // manual config has no columns by default | |||||
AddLogger(DefaultConfig.Instance.GetLoggers().ToArray()); // manual config has no loggers by default | |||||
AddExporter(DefaultConfig.Instance.GetExporters().ToArray()); // manual config has no exporters by default | |||||
AddColumnProvider(DefaultConfig.Instance.GetColumnProviders().ToArray()); // manual config has no columns by default | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -9,8 +9,8 @@ namespace MQTTnet.Benchmarks.Configurations | |||||
{ | { | ||||
public RuntimeCompareConfig() | public RuntimeCompareConfig() | ||||
{ | { | ||||
Add(Job.Default.With(ClrRuntime.Net472)); | |||||
Add(Job.Default.With(CoreRuntime.Core22).With(CsProjCoreToolchain.NetCoreApp22)); | |||||
AddJob(Job.Default.WithRuntime(ClrRuntime.Net472)); | |||||
AddJob(Job.Default.WithRuntime(CoreRuntime.Core22).WithToolchain(CsProjCoreToolchain.NetCoreApp22)); | |||||
} | } | ||||
} | } | ||||
@@ -12,18 +12,14 @@ namespace MQTTnet.Tests.Mockups | |||||
return new MqttNetScopedLogger(this, source); | return new MqttNetScopedLogger(this, source); | ||||
} | } | ||||
public void Publish(MqttNetLogLevel logLevel, string message, object[] parameters, Exception exception) | |||||
public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception) | |||||
{ | { | ||||
LogMessagePublished?.Invoke(this, new MqttNetLogMessagePublishedEventArgs(new MqttNetLogMessage | LogMessagePublished?.Invoke(this, new MqttNetLogMessagePublishedEventArgs(new MqttNetLogMessage | ||||
{ | { | ||||
Level = logLevel, | Level = logLevel, | ||||
Message = message | |||||
Message = string.Format(message, parameters), | |||||
Exception = exception | |||||
})); | })); | ||||
} | } | ||||
public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception) | |||||
{ | |||||
throw new NotImplementedException(); | |||||
} | |||||
} | } | ||||
} | } |
@@ -6,16 +6,16 @@ using Newtonsoft.Json; | |||||
namespace MQTTnet.TestApp.UniversalWindows | namespace MQTTnet.TestApp.UniversalWindows | ||||
{ | { | ||||
public class JsonServerStorage : IMqttServerStorage | |||||
public sealed class JsonServerStorage : IMqttServerStorage | |||||
{ | { | ||||
private readonly string _filename = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "Retained.json"); | |||||
readonly string _filename = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "Retained.json"); | |||||
public async Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages) | |||||
public Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages) | |||||
{ | { | ||||
await Task.CompletedTask; | |||||
var json = JsonConvert.SerializeObject(messages); | var json = JsonConvert.SerializeObject(messages); | ||||
File.WriteAllText(_filename, json); | File.WriteAllText(_filename, json); | ||||
return Task.CompletedTask; | |||||
} | } | ||||
public async Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync() | public async Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync() | ||||
@@ -105,6 +105,9 @@ | |||||
<AppxManifest Include="Package.appxmanifest"> | <AppxManifest Include="Package.appxmanifest"> | ||||
<SubType>Designer</SubType> | <SubType>Designer</SubType> | ||||
</AppxManifest> | </AppxManifest> | ||||
<None Include="..\..\.editorconfig"> | |||||
<Link>.editorconfig</Link> | |||||
</None> | |||||
<None Include="MQTTnet.TestApp.UniversalWindows_TemporaryKey.pfx" /> | <None Include="MQTTnet.TestApp.UniversalWindows_TemporaryKey.pfx" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||