Compare commits

...
5 Commits
9 changed files with 109 additions and 34 deletions
+3 -16
View File
@@ -12,22 +12,9 @@
<requireLicenseAcceptance>true</requireLicenseAcceptance> <requireLicenseAcceptance>true</requireLicenseAcceptance>
<description>MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker) and supports v3.1.0, v3.1.1 and v5.0.0 of the MQTT protocol.</description> <description>MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker) and supports v3.1.0, v3.1.1 and v5.0.0 of the MQTT protocol.</description>
<releaseNotes> <releaseNotes>
* [Core] Improved logger performance (BREAKING CHANGE!). * [Client] Fixed issue in keep alive handling.
* [Core] Renamed some topic filter relevant classes (BREAKING CHANGE!). * [MQTTnet.Server] Added support for delivering static files (HTML, JavaScript etc.).
* [Core] Improved task management for UWP connections (thanks to @xgstation). * [MQTTnet.Server] Fixed web socket protocol errors (when using paho JS etc.).
* [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 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 TCP based connections trying to reconnect with an offline server.
* [Client] Fixed an issue when connecting to an invalid host (format).
* [Client] Added support for user properties in CONNECT packet.
* [Client] Removed _KeepAliveSendInterval_ and improved keep alive handling (BREAKING CHANGE!).
* [ManagedClient] Added method to trigger PING/PONG manually (connection check etc.).
* [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1.
* [MQTTnet.AspNetCore] Fixed several packaging issues with the Nuget package.
* [MQTTnet.Server] Fixed wrong version output.
</releaseNotes> </releaseNotes>
<copyright>Copyright Christian Kratky 2016-2020</copyright> <copyright>Copyright Christian Kratky 2016-2020</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> <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>
+9 -8
View File
@@ -29,13 +29,6 @@
<NoWarn>1701;1702</NoWarn> <NoWarn>1701;1702</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Compile Remove="wwwroot\**" />
<Content Remove="wwwroot\**" />
<EmbeddedResource Remove="wwwroot\**" />
<None Remove="wwwroot\**" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Content Update="appsettings.json"> <Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -72,11 +65,19 @@
<None Update="Web\authorization_handler.py"> <None Update="Web\authorization_handler.py">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Update="Web\wwwroot\Hello.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Web\wwwroot\mqtt_Test.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Web\wwwroot\pahoJS_Test.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Properties\PublishProfiles\" /> <Folder Include="Properties\PublishProfiles\" />
<Folder Include="Web\wwwroot\" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+2 -1
View File
@@ -3,6 +3,7 @@ using Microsoft.Extensions.Hosting;
using MQTTnet.Server.Web; using MQTTnet.Server.Web;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Reflection; using System.Reflection;
namespace MQTTnet.Server namespace MQTTnet.Server
@@ -21,8 +22,8 @@ namespace MQTTnet.Server
webBuilder.ConfigureKestrel(serverOptions => webBuilder.ConfigureKestrel(serverOptions =>
{ {
}) })
.UseWebRoot(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Web", "wwwroot"))
.UseStartup<Startup>(); .UseStartup<Startup>();
}).Build().Run(); }).Build().Run();
return 0; return 0;
+11 -4
View File
@@ -6,6 +6,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using Microsoft.Scripting.Utils; using Microsoft.Scripting.Utils;
using MQTTnet.AspNetCore;
using MQTTnet.Server.Configuration; using MQTTnet.Server.Configuration;
using MQTTnet.Server.Logging; using MQTTnet.Server.Logging;
using MQTTnet.Server.Mqtt; using MQTTnet.Server.Mqtt;
@@ -40,6 +41,9 @@ namespace MQTTnet.Server.Web
DataSharingService dataSharingService, DataSharingService dataSharingService,
MqttSettingsModel mqttSettings) MqttSettingsModel mqttSettings)
{ {
application.UseDefaultFiles();
application.UseStaticFiles();
application.UseHsts(); application.UseHsts();
application.UseRouting(); application.UseRouting();
application.UseCors(x => x application.UseCors(x => x
@@ -50,8 +54,6 @@ namespace MQTTnet.Server.Web
application.UseAuthentication(); application.UseAuthentication();
application.UseAuthorization(); application.UseAuthorization();
application.UseStaticFiles();
application.UseEndpoints(endpoints => application.UseEndpoints(endpoints =>
{ {
endpoints.MapControllers(); endpoints.MapControllers();
@@ -81,7 +83,6 @@ namespace MQTTnet.Server.Web
{ {
services.AddCors(); services.AddCors();
services.AddControllers(); services.AddControllers();
services.AddMvc() services.AddMvc()
@@ -197,7 +198,13 @@ namespace MQTTnet.Server.Web
{ {
if (context.WebSockets.IsWebSocketRequest) if (context.WebSockets.IsWebSocketRequest)
{ {
using (var webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false)) string subProtocol = null;
if (context.Request.Headers.TryGetValue("Sec-WebSocket-Protocol", out var requestedSubProtocolValues))
{
subProtocol = MqttSubProtocolSelector.SelectSubProtocol(requestedSubProtocolValues);
}
using (var webSocket = await context.WebSockets.AcceptWebSocketAsync(subProtocol).ConfigureAwait(false))
{ {
await mqttServerService.RunWebSocketConnectionAsync(webSocket, context).ConfigureAwait(false); await mqttServerService.RunWebSocketConnectionAsync(webSocket, context).ConfigureAwait(false);
} }
@@ -0,0 +1 @@
World
@@ -0,0 +1,33 @@
<html>
<head>
<title>MQTT JS Example</title>
<script src="https://cdn.jsdelivr.net/npm/mqtt@4.0.1/dist/mqtt.min.js" type="text/javascript"></script>
<script type="text/javascript">
var client = mqtt.connect('ws://localhost:80/mqtt')
client.on('connect', function () {
client.subscribe('mqtt_subscription', function (err) {
console.log("Subscribed");
})
})
client.on('message', function (topic, message) {
console.log(topic);
console.log(message.toString())
})
function buttonClick() {
client.publish("MQTT_JS_TOPIC", "payload");
}
</script>
</head>
<body>
<button onclick="buttonClick()">Publish</button>
</body>
</html>
@@ -0,0 +1,41 @@
<html>
<head>
<title>paho JS Example</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
<script type="text/javascript">
var mqttClient = new Paho.MQTT.Client("localhost", 80, "/mqtt", "pahoJS_client");
mqttClient.onConnectionLost = onConnectionLost;
mqttClient.onMessageArrived = onMessageArrived;
mqttClient.connect({ onSuccess: onConnect });
function onConnect() {
console.log("MQTT client connected");
mqttClient.subscribe("pahoJS_subscription");
}
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:" + responseObject.errorMessage);
}
}
function onMessageArrived(message) {
console.log("onMessageArrived:" + message.payloadString);
}
function buttonClick() {
message = new Paho.MQTT.Message("Hello");
message.destinationName = "pahoJS_topic";
mqttClient.send(message);
}
</script>
</head>
<body>
<button onclick="buttonClick()">Publish</button>
</body>
</html>
+3 -3
View File
@@ -25,7 +25,7 @@ namespace MQTTnet.Adapter
readonly byte[] _fixedHeaderBuffer = new byte[2]; readonly byte[] _fixedHeaderBuffer = new byte[2];
SemaphoreSlim _writerSemaphore = new SemaphoreSlim(1, 1); readonly SemaphoreSlim _writerSemaphore = new SemaphoreSlim(1, 1);
long _bytesReceived; long _bytesReceived;
long _bytesSent; long _bytesSent;
@@ -111,6 +111,8 @@ namespace MQTTnet.Adapter
public async Task SendPacketAsync(MqttBasePacket packet, TimeSpan timeout, CancellationToken cancellationToken) public async Task SendPacketAsync(MqttBasePacket packet, TimeSpan timeout, CancellationToken cancellationToken)
{ {
ThrowIfDisposed();
await _writerSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); await _writerSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try try
{ {
@@ -211,9 +213,7 @@ namespace MQTTnet.Adapter
if (disposing) if (disposing)
{ {
_channel?.Dispose(); _channel?.Dispose();
_writerSemaphore?.Dispose(); _writerSemaphore?.Dispose();
_writerSemaphore = null;
} }
base.Dispose(disposing); base.Dispose(disposing);
+5 -1
View File
@@ -446,7 +446,11 @@ namespace MQTTnet.Client
await SendAndReceiveAsync<MqttPingRespPacket>(new MqttPingReqPacket(), cancellationToken).ConfigureAwait(false); await SendAndReceiveAsync<MqttPingRespPacket>(new MqttPingReqPacket(), cancellationToken).ConfigureAwait(false);
} }
await Task.Delay(keepAlivePeriod, cancellationToken).ConfigureAwait(false); // Wait a fixed time in all cases. Calculation of the remaining time is complicated
// due to some edge cases and was buggy in the past. Now we wait half a second because the
// min keep alive value is one second so that the server will wait 1.5 seconds for a PING
// packet.
await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken).ConfigureAwait(false);
} }
} }
catch (Exception exception) catch (Exception exception)