Преглед изворни кода

Extend MQTTnet.Server application.

release/3.x.x
Christian пре 5 година
родитељ
комит
6f5f507323
32 измењених фајлова са 1114 додато и 309 уклоњено
  1. +1
    -1
      MQTTnet.sln
  2. +1
    -0
      MQTTnet.sln.DotSettings
  3. +0
    -1
      Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs
  4. +9
    -0
      Source/MQTTnet.Server/Configuration/EndpointConfiguration.cs
  5. +1
    -1
      Source/MQTTnet.Server/Configuration/ListenModel.cs
  6. +1
    -1
      Source/MQTTnet.Server/Configuration/ListenProtocolTypes.cs
  7. +7
    -0
      Source/MQTTnet.Server/Configuration/MqttNetServerConfiguration.cs
  8. +1
    -1
      Source/MQTTnet.Server/Configuration/SettingsModel.cs
  9. +2
    -5
      Source/MQTTnet.Server/Controllers/ValuesController.cs
  10. +21
    -0
      Source/MQTTnet.Server/LICENSE
  11. +43
    -0
      Source/MQTTnet.Server/Logging/MqttNetChildLoggerWrapper.cs
  12. +48
    -0
      Source/MQTTnet.Server/Logging/MqttNetLoggerWrapper.cs
  13. +24
    -4
      Source/MQTTnet.Server/MQTTnet.Server.csproj
  14. +50
    -0
      Source/MQTTnet.Server/Mqtt/MqttApplicationMessageInterceptor.cs
  15. +46
    -0
      Source/MQTTnet.Server/Mqtt/MqttConnectionValidator.cs
  16. +101
    -0
      Source/MQTTnet.Server/Mqtt/MqttServerService.cs
  17. +47
    -0
      Source/MQTTnet.Server/Mqtt/MqttSubscriptionInterceptor.cs
  18. +143
    -0
      Source/MQTTnet.Server/Program.cs
  19. +47
    -0
      Source/MQTTnet.Server/Scripting/DataSharing/DataSharingService.cs
  20. +88
    -0
      Source/MQTTnet.Server/Scripting/PythonConvert.cs
  21. +66
    -0
      Source/MQTTnet.Server/Scripting/PythonIOStream.cs
  22. +130
    -0
      Source/MQTTnet.Server/Scripting/PythonScriptHostService.cs
  23. +57
    -0
      Source/MQTTnet.Server/Scripting/PythonScriptInstance.cs
  24. +74
    -0
      Source/MQTTnet.Server/Scripts/00_sample.py
  25. +19
    -0
      Source/MQTTnet.Server/Scripts/readme.md
  26. +69
    -0
      Source/MQTTnet.Server/Startup.cs
  27. +0
    -0
      Source/MQTTnet.Server/appsettings.Development.json
  28. +0
    -0
      Source/MQTTnet.Server/appsettings.json
  29. +18
    -0
      Source/MQTTnet/MqttFactory.cs
  30. +0
    -116
      Source/MQTTnetServer/MQTTnetServer.xml
  31. +0
    -118
      Source/MQTTnetServer/Program.cs
  32. +0
    -61
      Source/MQTTnetServer/Startup.cs

+ 1
- 1
MQTTnet.sln Прегледај датотеку

@@ -47,7 +47,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.ManagedC
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore.Tests", "Tests\MQTTnet.AspNetCore.Tests\MQTTnet.AspNetCore.Tests.csproj", "{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnetServer", "Source\MQTTnetServer\MQTTnetServer.csproj", "{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Server", "Source\MQTTnet.Server\MQTTnet.Server.csproj", "{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution


+ 1
- 0
MQTTnet.sln.DotSettings Прегледај датотеку

@@ -7,6 +7,7 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>

+ 0
- 1
Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs Прегледај датотеку

@@ -40,7 +40,6 @@ namespace MQTTnet.AspNetCore

public void Dispose()
{
StopAsync().GetAwaiter().GetResult();
}
}
}

+ 9
- 0
Source/MQTTnet.Server/Configuration/EndpointConfiguration.cs Прегледај датотеку

@@ -0,0 +1,9 @@
namespace MQTTnet.Server.Configuration
{
public class EndpointConfiguration
{
public int Port { get; set; } = 1883;

public int BacklogSize { get; set; } = 10;
}
}

Source/MQTTnetServer/Settings/ListenModel.cs → Source/MQTTnet.Server/Configuration/ListenModel.cs Прегледај датотеку

@@ -1,4 +1,4 @@
namespace MQTTnetServer.Settings
namespace MQTTnet.Server.Configuration
{
/// <summary>
/// Listen Entry Settings Model

Source/MQTTnetServer/Settings/ListenProtocolTypes.cs → Source/MQTTnet.Server/Configuration/ListenProtocolTypes.cs Прегледај датотеку

@@ -1,4 +1,4 @@
namespace MQTTnetServer.Settings
namespace MQTTnet.Server.Configuration
{
/// <summary>
/// Listen Protocol Types

+ 7
- 0
Source/MQTTnet.Server/Configuration/MqttNetServerConfiguration.cs Прегледај датотеку

@@ -0,0 +1,7 @@
namespace MQTTnet.Server.Configuration
{
public class MqttNetServerConfiguration
{
}
}

Source/MQTTnetServer/Settings/SettingsModel.cs → Source/MQTTnet.Server/Configuration/SettingsModel.cs Прегледај датотеку

@@ -1,6 +1,6 @@
using System.Collections.Generic;

namespace MQTTnetServer.Settings
namespace MQTTnet.Server.Configuration
{
/// <summary>
/// Main Settings Model

Source/MQTTnetServer/Controllers/ValuesController.cs → Source/MQTTnet.Server/Controllers/ValuesController.cs Прегледај датотеку

@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

namespace MQTTnetServer.Controllers
namespace MQTTnet.Server.Controllers
{
[Route("api/[controller]")]
[ApiController]

+ 21
- 0
Source/MQTTnet.Server/LICENSE Прегледај датотеку

@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2017 Christian Kratky

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

+ 43
- 0
Source/MQTTnet.Server/Logging/MqttNetChildLoggerWrapper.cs Прегледај датотеку

@@ -0,0 +1,43 @@
using System;
using MQTTnet.Diagnostics;

namespace MQTTnet.Server.Logging
{
public class MqttNetChildLoggerWrapper : IMqttNetChildLogger
{
private readonly MqttNetLoggerWrapper _logger;
private readonly string _source;

public MqttNetChildLoggerWrapper(string source, MqttNetLoggerWrapper logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));

_source = source;
}

public IMqttNetChildLogger CreateChildLogger(string source = null)
{
return _logger.CreateChildLogger(source);
}

public void Verbose(string message, params object[] parameters)
{
_logger.Publish(MqttNetLogLevel.Verbose, _source, message, parameters, null);
}

public void Info(string message, params object[] parameters)
{
_logger.Publish(MqttNetLogLevel.Info, _source, message, parameters, null);
}

public void Warning(Exception exception, string message, params object[] parameters)
{
_logger.Publish(MqttNetLogLevel.Warning, _source, message, parameters, exception);
}

public void Error(Exception exception, string message, params object[] parameters)
{
_logger.Publish(MqttNetLogLevel.Error, _source, message, parameters, exception);
}
}
}

+ 48
- 0
Source/MQTTnet.Server/Logging/MqttNetLoggerWrapper.cs Прегледај датотеку

@@ -0,0 +1,48 @@
using System;
using Microsoft.Extensions.Logging;
using MQTTnet.Diagnostics;

namespace MQTTnet.Server.Logging
{
public class MqttNetLoggerWrapper : IMqttNetLogger
{
private readonly ILogger<MqttServer> _logger;

public MqttNetLoggerWrapper(ILogger<MqttServer> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public event EventHandler<MqttNetLogMessagePublishedEventArgs> LogMessagePublished;
public IMqttNetChildLogger CreateChildLogger(string source = null)
{
return new MqttNetChildLoggerWrapper(source, this);
}

public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception)
{
var convertedLogLevel = ConvertLogLevel(logLevel);

if (!_logger.IsEnabled(convertedLogLevel))
{
return;
}

_logger.Log(convertedLogLevel, exception, message, parameters);
}

private static LogLevel ConvertLogLevel(MqttNetLogLevel logLevel)
{
switch (logLevel)
{
case MqttNetLogLevel.Error: return LogLevel.Error;
case MqttNetLogLevel.Warning: return LogLevel.Warning;
case MqttNetLogLevel.Info: return LogLevel.Information;
case MqttNetLogLevel.Verbose: return LogLevel.Trace;
}

return LogLevel.Debug;
}
}
}

Source/MQTTnetServer/MQTTnetServer.csproj → Source/MQTTnet.Server/MQTTnet.Server.csproj Прегледај датотеку

@@ -3,11 +3,11 @@
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<AssemblyName>MQTTnetServer</AssemblyName>
<RootNamespace>MQTTnetServer</RootNamespace>
<AssemblyName>MQTTnet.Server</AssemblyName>
<RootNamespace>MQTTnet.Server</RootNamespace>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<Company />
<Product />
<Product>MQTTnet</Product>
<Description />
<Authors />
<PackageId />
@@ -16,8 +16,12 @@
<LangVersion>latest</LangVersion>
</PropertyGroup>

<PropertyGroup>
<StartupObject></StartupObject>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>MQTTnetServer.xml</DocumentationFile>
<DocumentationFile></DocumentationFile>
<WarningsAsErrors>NU1605</WarningsAsErrors>
<NoWarn>1701;1702</NoWarn>
</PropertyGroup>
@@ -29,8 +33,12 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="IronPython" Version="2.7.9" />
<PackageReference Include="IronPython.StdLib" Version="2.7.9" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="4.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="4.0.1" />
</ItemGroup>

<ItemGroup>
@@ -38,4 +46,16 @@
<ProjectReference Include="..\MQTTnet\MQTTnet.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="LICENSE">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Scripts\readme.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Scripts\00_sample.py">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>

+ 50
- 0
Source/MQTTnet.Server/Mqtt/MqttApplicationMessageInterceptor.cs Прегледај датотеку

@@ -0,0 +1,50 @@
using System;
using System.Threading.Tasks;
using IronPython.Runtime;
using Microsoft.Extensions.Logging;
using MQTTnet.Protocol;
using MQTTnet.Server.Scripting;

namespace MQTTnet.Server.Mqtt
{
public class MqttApplicationMessageInterceptor : IMqttServerApplicationMessageInterceptor
{
private readonly PythonScriptHostService _pythonScriptHostService;
private readonly ILogger<MqttApplicationMessageInterceptor> _logger;

public MqttApplicationMessageInterceptor(PythonScriptHostService pythonScriptHostService, ILogger<MqttApplicationMessageInterceptor> logger)
{
_pythonScriptHostService = pythonScriptHostService ?? throw new ArgumentNullException(nameof(pythonScriptHostService));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context)
{
try
{
var pythonContext = new PythonDictionary
{
{ "accept_publish", context.AcceptPublish },
{ "close_connection", context.CloseConnection },
{ "client_id", context.ClientId },
{ "topic", context.ApplicationMessage.Topic },
{ "qos", (int)context.ApplicationMessage.QualityOfServiceLevel },
{ "retain", context.ApplicationMessage.Retain }
};

_pythonScriptHostService.InvokeOptionalFunction("on_intercept_application_message", pythonContext);

context.AcceptPublish = (bool)pythonContext.get("accept_publish", context.AcceptPublish);
context.CloseConnection = (bool)pythonContext.get("close_connection", context.CloseConnection);
context.ApplicationMessage.Topic = (string)pythonContext.get("topic", context.ApplicationMessage.Topic);
context.ApplicationMessage.QualityOfServiceLevel = (MqttQualityOfServiceLevel)(int)pythonContext.get("qos", (int)context.ApplicationMessage.QualityOfServiceLevel);
}
catch (Exception exception)
{
_logger.LogError(exception, "Error while intercepting application message.");
}

return Task.CompletedTask;
}
}
}

+ 46
- 0
Source/MQTTnet.Server/Mqtt/MqttConnectionValidator.cs Прегледај датотеку

@@ -0,0 +1,46 @@
using System;
using System.Threading.Tasks;
using IronPython.Runtime;
using Microsoft.Extensions.Logging;
using MQTTnet.Protocol;
using MQTTnet.Server.Scripting;

namespace MQTTnet.Server.Mqtt
{
public class MqttConnectionValidator : IMqttServerConnectionValidator
{
private readonly PythonScriptHostService _pythonScriptHostService;
private readonly ILogger<MqttConnectionValidator> _logger;

public MqttConnectionValidator(PythonScriptHostService pythonScriptHostService, ILogger<MqttConnectionValidator> logger)
{
_pythonScriptHostService = pythonScriptHostService ?? throw new ArgumentNullException(nameof(pythonScriptHostService));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public Task ValidateConnectionAsync(MqttConnectionValidatorContext context)
{
try
{
var pythonContext = new PythonDictionary
{
{ "client_id", context.ClientId },
{ "endpoint", context.Endpoint },
{ "username", context.Username },
{ "password", context.Password },
{ "result", PythonConvert.Pythonfy(context.ReturnCode) }
};

_pythonScriptHostService.InvokeOptionalFunction("on_validate_client_connection", pythonContext);

context.ReturnCode = PythonConvert.ParseEnum<MqttConnectReturnCode>((string)pythonContext["result"]);
}
catch (Exception exception)
{
_logger.LogError(exception, "Error while validating client connection.");
}

return Task.CompletedTask;
}
}
}

+ 101
- 0
Source/MQTTnet.Server/Mqtt/MqttServerService.cs Прегледај датотеку

@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Runtime;
using Microsoft.Extensions.Logging;
using MQTTnet.Adapter;
using MQTTnet.AspNetCore;
using MQTTnet.Implementations;
using MQTTnet.Protocol;
using MQTTnet.Server.Logging;
using MQTTnet.Server.Scripting;

namespace MQTTnet.Server.Mqtt
{
public class MqttServerService
{
private readonly ILogger<MqttServerService> _logger;

private readonly MqttConnectionValidator _mqttConnectionValidator;
private readonly MqttSubscriptionInterceptor _mqttSubscriptionInterceptor;
private readonly MqttApplicationMessageInterceptor _mqttApplicationMessageInterceptor;
private readonly PythonScriptHostService _pythonScriptHostService;

private readonly IMqttServer _mqttServer;

public MqttServerService(
IMqttServerFactory mqttServerFactory,
MqttWebSocketServerAdapter webSocketServerAdapter,
MqttNetLoggerWrapper mqttNetLogger,
MqttConnectionValidator mqttConnectionValidator,
MqttSubscriptionInterceptor mqttSubscriptionInterceptor,
MqttApplicationMessageInterceptor mqttApplicationMessageInterceptor,
PythonScriptHostService pythonScriptHostService,
ILogger<MqttServerService> logger)
{
_mqttConnectionValidator = mqttConnectionValidator ?? throw new ArgumentNullException(nameof(mqttConnectionValidator));
_mqttSubscriptionInterceptor = mqttSubscriptionInterceptor ?? throw new ArgumentNullException(nameof(mqttSubscriptionInterceptor));
_mqttApplicationMessageInterceptor = mqttApplicationMessageInterceptor ?? throw new ArgumentNullException(nameof(mqttApplicationMessageInterceptor));
_pythonScriptHostService = pythonScriptHostService ?? throw new ArgumentNullException(nameof(pythonScriptHostService));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));

var adapters = new List<IMqttServerAdapter>
{
new MqttTcpServerAdapter(new MqttNetChildLoggerWrapper(null, mqttNetLogger)),
webSocketServerAdapter
};

_mqttServer = mqttServerFactory.CreateMqttServer(adapters);
}

public void Configure()
{
_pythonScriptHostService.RegisterProxyObject("publish", new Action<PythonDictionary>(Publish));

var options = new MqttServerOptionsBuilder()
.WithDefaultEndpoint()
.WithDefaultEndpointPort(1883)
.WithConnectionValidator(_mqttConnectionValidator)
.WithApplicationMessageInterceptor(_mqttApplicationMessageInterceptor)
.WithSubscriptionInterceptor(_mqttSubscriptionInterceptor)
.Build();

_mqttServer.StartAsync(options).GetAwaiter().GetResult();

_logger.LogInformation("MQTT server started.");
}

private void Publish(PythonDictionary parameters)
{
var applicationMessageBuilder = new MqttApplicationMessageBuilder()
.WithTopic((string)parameters.get("topic", null))
.WithRetainFlag((bool)parameters.get("retain", false))
.WithQualityOfServiceLevel((MqttQualityOfServiceLevel)(int)parameters.get("qos", 0));

var payload = parameters.get("payload", null);
var binaryPayload = new byte[0];

if (payload is string stringPayload)
{
binaryPayload = Encoding.UTF8.GetBytes(stringPayload);
}
else if (payload is ByteArray byteArray)
{
binaryPayload = byteArray.ToArray();
}
else if (payload is IEnumerable<int> intArray)
{
binaryPayload = intArray.Select(Convert.ToByte).ToArray();
}

applicationMessageBuilder = applicationMessageBuilder
.WithPayload(binaryPayload);

var applicationMessage = applicationMessageBuilder.Build();

_mqttServer.PublishAsync(applicationMessage).GetAwaiter().GetResult();
_logger.LogInformation($"Published topic '{applicationMessage.Topic}' from server.");
}
}
}

+ 47
- 0
Source/MQTTnet.Server/Mqtt/MqttSubscriptionInterceptor.cs Прегледај датотеку

@@ -0,0 +1,47 @@
using System;
using System.Threading.Tasks;
using IronPython.Runtime;
using Microsoft.Extensions.Logging;
using MQTTnet.Server.Scripting;

namespace MQTTnet.Server.Mqtt
{
public class MqttSubscriptionInterceptor : IMqttServerSubscriptionInterceptor
{
private readonly PythonScriptHostService _pythonScriptHostService;
private readonly ILogger<MqttSubscriptionInterceptor> _logger;

public MqttSubscriptionInterceptor(PythonScriptHostService pythonScriptHostService, ILogger<MqttSubscriptionInterceptor> logger)
{
_pythonScriptHostService = pythonScriptHostService ?? throw new ArgumentNullException(nameof(pythonScriptHostService));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public Task InterceptSubscriptionAsync(MqttSubscriptionInterceptorContext context)
{
try
{
var pythonContext = new PythonDictionary
{
{ "accept_subscription", context.AcceptSubscription },
{ "close_connection", context.CloseConnection },

{ "client_id", context.ClientId },
{ "topic", context.TopicFilter.Topic },
{ "qos", (int)context.TopicFilter.QualityOfServiceLevel }
};

_pythonScriptHostService.InvokeOptionalFunction("on_intercept_subscription", pythonContext);

context.AcceptSubscription = (bool)pythonContext["accept_subscription"];
context.CloseConnection = (bool)pythonContext["close_connection"];
}
catch (Exception exception)
{
_logger.LogError(exception, "Error while intercepting subscription.");
}

return Task.CompletedTask;
}
}
}

+ 143
- 0
Source/MQTTnet.Server/Program.cs Прегледај датотеку

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using MQTTnet.Server.Configuration;

namespace MQTTnet.Server
{
public static class Program
{
public static int Main(string[] args)
{
try
{
PrintLogo();

CreateWebHostBuilder(args).Build().Run();
return 0;
}
catch (Exception exception)
{
Console.WriteLine(exception);
return -1;
}
}

private static void PrintLogo()
{
Console.ForegroundColor = ConsoleColor.Red;

Console.WriteLine(@"
__ __ ____ _______ _______ _ _____
| \/ |/ __ \__ __|__ __| | | / ____|
| \ / | | | | | | | |_ __ ___| |_ | (___ ___ _ ____ _____ _ __
| |\/| | | | | | | | | '_ \ / _ \ __| \___ \ / _ \ '__\ \ / / _ \ '__|
| | | | |__| | | | | | | | | __/ |_ ____) | __/ | \ V / __/ |
|_| |_|\___\_\ |_| |_|_| |_|\___|\__| |_____/ \___|_| \_/ \___|_|");

Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(@"
-- The official MQTT server implementation of MQTTnet --
Copyright (c) 2017-2019 The MQTTnet Team");

Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine(@"
https://github.com/chkr1011/MQTTnet");

Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(@"
Version: 1.0.0-alpha1
License: MIT (read LICENSE file)
");

Console.BackgroundColor = ConsoleColor.White;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(" ! THIS IS AN ALPHA VERSION! IT IS NOT RECOMMENDED TO USE IT FOR ANY DIFFERENT PURPOSE THAN TESTING OR EVALUATING!");
Console.WriteLine();
}

private static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
var webHost = WebHost.CreateDefaultBuilder(args)
.UseKestrel(kestrelOptions =>
{
kestrelOptions.ListenAnyIP(80, listenOptions =>
{
listenOptions.NoDelay = true;
});
});
//var listen = ReadListenSettings();
//webHost
// .UseKestrel(o =>
// {
// if (listen?.Length > 0)
// {
// foreach (var item in listen)
// {
// if (item.Address?.Trim() == "*")
// {
// if (item.Protocol == ListenProtocolTypes.MQTT)
// {
// o.ListenAnyIP(item.Port, c => c.UseMqtt());
// }
// else
// {
// o.ListenAnyIP(item.Port);
// }
// }
// else if (item.Address?.Trim() == "localhost")
// {
// if (item.Protocol == ListenProtocolTypes.MQTT)
// {
// o.ListenLocalhost(item.Port, c => c.UseMqtt());
// }
// else
// {
// o.ListenLocalhost(item.Port);
// }
// }
// else
// {
// if (IPAddress.TryParse(item.Address, out var ip))
// {
// if (item.Protocol == ListenProtocolTypes.MQTT)
// {
// o.Listen(ip, item.Port, c => c.UseMqtt());
// }
// else
// {
// o.Listen(ip, item.Port);
// }
// }
// }
// }
// }
// else
// {
// o.ListenAnyIP(1883, l => l.UseMqtt());
// o.ListenAnyIP(5000);
// }
// });

webHost.UseStartup<Startup>();

return webHost;
}

public static ListenModel[] ReadListenSettings()
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.Build();

var listen = new List<ListenModel>();
builder.Bind("MQTTnetServer:Listen", listen);

return listen.ToArray();
}
}
}

+ 47
- 0
Source/MQTTnet.Server/Scripting/DataSharing/DataSharingService.cs Прегледај датотеку

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;

namespace MQTTnet.Server.Scripting.DataSharing
{
public class DataSharingService
{
private readonly Dictionary<string, object> _storage = new Dictionary<string, object>();
private readonly PythonScriptHostService _pythonScriptHostService;
private readonly ILogger<DataSharingService> _logger;

public DataSharingService(PythonScriptHostService pythonScriptHostService, ILogger<DataSharingService> logger)
{
_pythonScriptHostService = pythonScriptHostService ?? throw new ArgumentNullException(nameof(pythonScriptHostService));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public void Configure()
{
_pythonScriptHostService.RegisterProxyObject("write_shared_data", new Action<string, object>(Write));
_pythonScriptHostService.RegisterProxyObject("read_shared_data", new Func<string, object, object>(Read));
}

public void Write(string key, object value)
{
lock (_storage)
{
_storage[key] = value;
_logger.LogInformation($"Shared data with key '{key}' updated.");
}
}

public object Read(string key, object defaultValue)
{
lock (_storage)
{
if (!_storage.TryGetValue(key, out var value))
{
return defaultValue;
}

return value;
}
}
}
}

+ 88
- 0
Source/MQTTnet.Server/Scripting/PythonConvert.cs Прегледај датотеку

@@ -0,0 +1,88 @@
using System;
using System.Collections;
using System.Text;
using IronPython.Runtime;

namespace MQTTnet.Server.Scripting
{
public static class PythonConvert
{
public static object ToPython(object value)
{
if (value is PythonDictionary)
{
return value;
}

if (value is string)
{
return value;
}

if (value is int)
{
return value;
}

if (value is float)
{
return value;
}

if (value is bool)
{
return value;
}

if (value is IDictionary dictionary)
{
var pythonDictionary = new PythonDictionary();
foreach (DictionaryEntry dictionaryEntry in dictionary)
{
pythonDictionary.Add(dictionaryEntry.Key, ToPython(dictionaryEntry.Value));
}

return pythonDictionary;
}

if (value is IEnumerable enumerable)
{
var pythonList = new List();
foreach (var item in enumerable)
{
pythonList.Add(ToPython(item));
}

return pythonList;
}

return value;
}

public static string Pythonfy(Enum value)
{
return Pythonfy(value.ToString());
}

public static string Pythonfy(string value)
{
var result = new StringBuilder();
foreach (var @char in value)
{
if (char.IsUpper(@char) && result.Length > 0)
{
result.Append('_');
}

result.Append(char.ToLowerInvariant(@char));
}

return result.ToString();
}

public static TEnum ParseEnum<TEnum>(string value) where TEnum : Enum
{
return (TEnum)Enum.Parse(typeof(TEnum), value.Replace("_", string.Empty), true);
}
}
}

+ 66
- 0
Source/MQTTnet.Server/Scripting/PythonIOStream.cs Прегледај датотеку

@@ -0,0 +1,66 @@
using System;
using System.IO;
using System.Text;
using Microsoft.Extensions.Logging;

namespace MQTTnet.Server.Scripting
{
public class PythonIOStream : Stream
{
private readonly ILogger _logger;
private readonly Encoding _encoder = Encoding.UTF8;

public PythonIOStream(ILogger<PythonIOStream> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public override void Flush()
{
}

public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}

public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}

public override void SetLength(long value)
{
throw new NotSupportedException();
}

public override void Write(byte[] buffer, int offset, int count)
{
if (buffer == null) throw new ArgumentNullException(nameof(buffer));

if (count == 0)
{
return;
}

var text = _encoder.GetString(buffer, offset, count);
if (text.Equals(Environment.NewLine))
{
return;
}

_logger.LogDebug(text);
}

public override bool CanRead { get; } = false;
public override bool CanSeek { get; } = false;
public override bool CanWrite { get; } = true;
public override long Length { get; } = 0L;

public override long Position
{
get => throw new NotSupportedException();
set => throw new NotSupportedException();
}
}
}

+ 130
- 0
Source/MQTTnet.Server/Scripting/PythonScriptHostService.cs Прегледај датотеку

@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Extensions.Logging;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;

namespace MQTTnet.Server.Scripting
{
public class PythonScriptHostService
{
private readonly IDictionary<string, object> _proxyObjects = new ExpandoObject();
private readonly List<PythonScriptInstance> _scriptInstances = new List<PythonScriptInstance>();
private readonly ILogger<PythonScriptHostService> _logger;
private readonly ScriptEngine _scriptEngine;
public PythonScriptHostService(PythonIOStream pythonIOStream, ILogger<PythonScriptHostService> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));

_scriptEngine = IronPython.Hosting.Python.CreateEngine();
_scriptEngine.Runtime.IO.SetOutput(pythonIOStream, Encoding.UTF8);
}

public void Configure()
{
AddSearchPaths(_scriptEngine);

var scriptsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Scripts");
foreach (var filename in Directory.GetFiles(scriptsDirectory, "*.py", SearchOption.AllDirectories).OrderBy(file => file))
{
TryInitializeScript(filename);
}
}

public void RegisterProxyObject(string name, object action)
{
if (name == null) throw new ArgumentNullException(nameof(name));
if (action == null) throw new ArgumentNullException(nameof(action));

_proxyObjects.Add(name, action);
}

public void InvokeOptionalFunction(string name, object parameters)
{
if (name == null) throw new ArgumentNullException(nameof(name));

lock (_scriptInstances)
{
foreach (var pythonScriptInstance in _scriptInstances)
{
try
{
pythonScriptInstance.InvokeOptionalFunction(name, parameters);
}
catch (Exception exception)
{
_logger.LogError(exception, $"Error while invoking function '{name}' at script '{pythonScriptInstance.Name}'.");
}
}
}
}

private void TryInitializeScript(string filename)
{
try
{
var scriptName = new FileInfo(filename).Name;

_logger.LogTrace($"Initializing Python script '{scriptName}'...");
var code = File.ReadAllText(filename);

var scriptInstance = CreateScriptInstance(scriptName, code);
scriptInstance.InvokeOptionalFunction("initialize");

_scriptInstances.Add(scriptInstance);

_logger.LogInformation($"Initialized script '{scriptName}'.");
}
catch (Exception exception)
{
_logger.LogError(exception, $"Error while initializing script '{new FileInfo(filename).Name}'.");
}
}

private PythonScriptInstance CreateScriptInstance(string name, string code)
{
var scriptScope = _scriptEngine.CreateScope();

var source = scriptScope.Engine.CreateScriptSourceFromString(code, SourceCodeKind.File);
var compiledCode = source.Compile();

scriptScope.SetVariable("mqtt_net_server", _proxyObjects);
compiledCode.Execute(scriptScope);
return new PythonScriptInstance(name, scriptScope);
}

private void AddSearchPaths(ScriptEngine scriptEngine)
{
var paths = new List<string>
{
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Lib"),
"/usr/lib/python2.7",
@"C:\Python27\Lib"
};
AddSearchPaths(scriptEngine, paths);
}

private void AddSearchPaths(ScriptEngine scriptEngine, IEnumerable<string> paths)
{
var searchPaths = scriptEngine.GetSearchPaths();

foreach (var path in paths)
{
if (Directory.Exists(path))
{
searchPaths.Add(path);
_logger.LogInformation($"Added Python lib path: {path}");
}
}

scriptEngine.SetSearchPaths(searchPaths);
}
}
}

+ 57
- 0
Source/MQTTnet.Server/Scripting/PythonScriptInstance.cs Прегледај датотеку

@@ -0,0 +1,57 @@
using System;
using IronPython.Runtime;
using Microsoft.Scripting.Hosting;

namespace MQTTnet.Server.Scripting
{
public class PythonScriptInstance
{
private readonly ScriptScope _scriptScope;

public PythonScriptInstance(string name, ScriptScope scriptScope)
{
_scriptScope = scriptScope;

Name = name;
}

public string Name { get; }

public bool InvokeOptionalFunction(string name, params object[] parameters)
{
return InvokeOptionalFunction(name, parameters, out _);
}

public bool InvokeOptionalFunction(string name, object[] parameters, out object result)
{
if (name == null) throw new ArgumentNullException(nameof(name));

lock (_scriptScope)
{
if (!_scriptScope.Engine.Operations.TryGetMember(_scriptScope, name, out var member))
{
result = null;
return false;
}

if (!(member is PythonFunction function))
{
throw new Exception($"Member '{name}' is no Python function.");
}

try
{
result = _scriptScope.Engine.Operations.Invoke(function, parameters);
return true;
}
catch (Exception exception)
{
var details = _scriptScope.Engine.GetService<ExceptionOperations>().FormatException(exception);
var message = $"Error while invoking function '{name}'. " + Environment.NewLine + details;

throw new Exception(message, exception);
}
}
}
}
}

+ 74
- 0
Source/MQTTnet.Server/Scripts/00_sample.py Прегледај датотеку

@@ -0,0 +1,74 @@
import json


def initialize():
"""
This function is invoked after the script file has been loaded.
It will be executed only one time.
"""

print("Hello World from Sample script.")

def on_validate_client_connection(context):
"""
This function is invoked whenever a client wants to connect. It can be used to validate the connection.
"""
print(context)

mqtt_net_server.write_shared_data(context["client_id"], {"custom_value_1": 1, "custom_value_2": True})

return

if context["client_id"] != "test_client":
context["result"] = "connection_refused_not_authorized"
return

if context["username"] != "bud spencer":
context["result"] = "connection_refused_not_authorized"
return

if context["password"] != "secret":
context["result"] = "connection_refused_not_authorized"

print(context)


def on_intercept_subscription(context):
"""
This function is invoked whenever a client wants to subscribe to a topic.
"""
print("Client '{client_id}' want's to subscribe to topic '{topic}'.".format(client_id=context["client_id"], topic=context["topic"]))


def on_intercept_application_message(context):
"""
This function is invoked for every processed application message. It also allows modifying
the message or cancel processing at all.
"""
client_id = context["client_id"]

if client_id != None:
shared_data = mqtt_net_server.read_shared_data(context["client_id"], {})
print(shared_data)

if context["topic"] == "topic_with_response":

json_payload = {
"hello": "world",
"x": 1,
"y": True,
"z": None
}

application_message = {
"retain": False,
"topic": "reply",
"payload": json.dumps(json_payload)
}

mqtt_net_server.publish(application_message)

print("Client '{client_id}' published topic '{topic}'.".format(client_id=context["client_id"], topic=context["topic"]))

+ 19
- 0
Source/MQTTnet.Server/Scripts/readme.md Прегледај датотеку

@@ -0,0 +1,19 @@
This directory contains scripts which are loaded by the server and can be used to perform the following tasks.

1. Validation of client connections via credentials, client IDs etc.
2. Manipulation of every processed message.
3. Validation of subscription attempts.
4. Publishing of custom application messages.

All scripts are loaded and _MQTTnet Server_ will invoke functions according to predefined naming conventions.
If a function is implemented in multiple scripts the context will be moved throug all instances. This allows overriding of results or passing data to other (following) scripts.

The Python starndard library ships with _MQTTnet Server_. But it is possible to add custom paths with Python libraries.

```
import sys
sys.path.append(PATH_TO_LIBRARY)
```

* All scripts must have the file extension _.py_.
* All scripts are sorted alphabetically (A to Z) before being loaded and parsed.

+ 69
- 0
Source/MQTTnet.Server/Startup.cs Прегледај датотеку

@@ -0,0 +1,69 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MQTTnet.AspNetCore;
using MQTTnet.Server.Logging;
using MQTTnet.Server.Mqtt;
using MQTTnet.Server.Scripting;
using MQTTnet.Server.Scripting.DataSharing;

namespace MQTTnet.Server
{
public class Startup
{
public Startup(IConfiguration configuration)
{
//var builder = new ConfigurationBuilder()
// .AddJsonFile("appsettings.json")
// .AddEnvironmentVariables();

//Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }

public void Configure(
IApplicationBuilder application,
IHostingEnvironment environment,
MqttServerService mqttServerService,
PythonScriptHostService pythonScriptHostService,
DataSharingService dataSharingService)
{
if (environment.IsDevelopment())
{
application.UseDeveloperExceptionPage();
}
else
{
application.UseHsts();
}

application.UseHttpsRedirection();
application.UseMvc();

dataSharingService.Configure();
pythonScriptHostService.Configure();
mqttServerService.Configure();
}

public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<MqttNetLoggerWrapper>();

services.AddSingleton<PythonIOStream>();
services.AddSingleton<PythonScriptHostService>();
services.AddSingleton<DataSharingService>();

services.AddSingleton<MqttWebSocketServerAdapter>();
services.AddSingleton<IMqttServerFactory, MqttFactory>();
services.AddSingleton<MqttServerService>();
services.AddSingleton<MqttConnectionValidator>();
services.AddSingleton<MqttSubscriptionInterceptor>();
services.AddSingleton<MqttApplicationMessageInterceptor>();

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
}
}

Source/MQTTnetServer/appsettings.Development.json → Source/MQTTnet.Server/appsettings.Development.json Прегледај датотеку


Source/MQTTnetServer/appsettings.json → Source/MQTTnet.Server/appsettings.json Прегледај датотеку


+ 18
- 0
Source/MQTTnet/MqttFactory.cs Прегледај датотеку

@@ -10,6 +10,17 @@ namespace MQTTnet
{
public class MqttFactory : IMqttClientFactory, IMqttServerFactory
{
private readonly IMqttNetLogger _logger;

public MqttFactory() : this(new MqttNetLogger())
{
}

public MqttFactory(IMqttNetLogger logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public IMqttClient CreateMqttClient()
{
return CreateMqttClient(new MqttNetLogger());
@@ -57,5 +68,12 @@ namespace MQTTnet

return new MqttServer(adapters, logger.CreateChildLogger());
}

public IMqttServer CreateMqttServer(IEnumerable<IMqttServerAdapter> adapters)
{
if (adapters == null) throw new ArgumentNullException(nameof(adapters));
return new MqttServer(adapters, _logger.CreateChildLogger());
}
}
}

+ 0
- 116
Source/MQTTnetServer/MQTTnetServer.xml Прегледај датотеку

@@ -1,116 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>MQTTnetServer</name>
</assembly>
<members>
<member name="T:MQTTnetServer.Program">
<summary>
Main Entry point
</summary>
</member>
<member name="M:MQTTnetServer.Program.Main(System.String[])">
<summary>
Main
</summary>
<param name="args"></param>
</member>
<member name="M:MQTTnetServer.Program.CreateWebHostBuilder(System.String[])">
<summary>
Configure and Start Kestrel
</summary>
<param name="args"></param>
<returns></returns>
</member>
<member name="M:MQTTnetServer.Program.ReadListenSettings">
<summary>
Read Application Settings
</summary>
<returns></returns>
</member>
<member name="T:MQTTnetServer.Settings.ListenModel">
<summary>
Listen Entry Settings Model
</summary>
</member>
<member name="M:MQTTnetServer.Settings.ListenModel.#ctor">
<summary>
Constructor
</summary>
</member>
<member name="P:MQTTnetServer.Settings.ListenModel.Address">
<summary>
Listen Address
</summary>
</member>
<member name="P:MQTTnetServer.Settings.ListenModel.Port">
<summary>
Listen Port
</summary>
</member>
<member name="P:MQTTnetServer.Settings.ListenModel.Protocol">
<summary>
Protocol Type
</summary>
</member>
<member name="T:MQTTnetServer.Settings.ListenProtocolTypes">
<summary>
Listen Protocol Types
</summary>
</member>
<member name="F:MQTTnetServer.Settings.ListenProtocolTypes.HTTP">
<summary>
HTTP
</summary>
</member>
<member name="F:MQTTnetServer.Settings.ListenProtocolTypes.HTTPS">
<summary>
HTTPS
</summary>
</member>
<member name="F:MQTTnetServer.Settings.ListenProtocolTypes.MQTT">
<summary>
MQTT
</summary>
</member>
<member name="T:MQTTnetServer.Settings.SettingsModel">
<summary>
Main Settings Model
</summary>
</member>
<member name="P:MQTTnetServer.Settings.SettingsModel.Listen">
<summary>
Listen Settings
</summary>
</member>
<member name="T:MQTTnetServer.Startup">
<summary>
Web App Startup
</summary>
</member>
<member name="M:MQTTnetServer.Startup.#ctor(Microsoft.Extensions.Configuration.IConfiguration)">
<summary>
Constructor
</summary>
<param name="configuration"></param>
</member>
<member name="P:MQTTnetServer.Startup.Configuration">
<summary>
Application Settings
</summary>
</member>
<member name="M:MQTTnetServer.Startup.Configure(Microsoft.AspNetCore.Builder.IApplicationBuilder,Microsoft.AspNetCore.Hosting.IHostingEnvironment)">
<summary>
This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
</summary>
<param name="app"></param>
<param name="env"></param>
</member>
<member name="M:MQTTnetServer.Startup.ConfigureServices(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
<summary>
This method gets called by the runtime. Use this method to add services to the container.
</summary>
<param name="services"></param>
</member>
</members>
</doc>

+ 0
- 118
Source/MQTTnetServer/Program.cs Прегледај датотеку

@@ -1,118 +0,0 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using MQTTnet.AspNetCore;
using MQTTnetServer.Settings;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;

namespace MQTTnetServer
{
/// <summary>
/// Main Entry point
/// </summary>
public class Program
{
/// <summary>
/// Main
/// </summary>
/// <param name="args"></param>
public static void Main(string[] args)
{
try
{
CreateWebHostBuilder(args).Build().Run();
}
catch (FileNotFoundException e)
{
Console.WriteLine("Could not find application settings file in: " + e.FileName);
return;
}
}

/// <summary>
/// Configure and Start Kestrel
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
var webHost = WebHost.CreateDefaultBuilder(args);
var listen = ReadListenSettings();
webHost
.UseKestrel(o =>
{
if (listen?.Length > 0)
{
foreach (var item in listen)
{
if (item.Address?.Trim() == "*")
{
if (item.Protocol == ListenProtocolTypes.MQTT)
{
o.ListenAnyIP(item.Port, c => c.UseMqtt());
}
else
{
o.ListenAnyIP(item.Port);
}
}
else if (item.Address?.Trim() == "localhost")
{
if (item.Protocol == ListenProtocolTypes.MQTT)
{
o.ListenLocalhost(item.Port, c => c.UseMqtt());
}
else
{
o.ListenLocalhost(item.Port);
}
}
else
{
if (IPAddress.TryParse(item.Address, out var ip))
{
if (item.Protocol == ListenProtocolTypes.MQTT)
{
o.Listen(ip, item.Port, c => c.UseMqtt());
}
else
{
o.Listen(ip, item.Port);
}
}
}
}
}
else
{
o.ListenAnyIP(1883, l => l.UseMqtt());
o.ListenAnyIP(5000);
}
});

webHost.UseStartup<Startup>();

return webHost;
}

/// <summary>
/// Read Application Settings
/// </summary>
/// <returns></returns>
public static ListenModel[] ReadListenSettings()
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.Build();

var listen = new List<ListenModel>();
builder.Bind("MQTTnetServer:Listen", listen);

return listen.ToArray();
}
}
}

+ 0
- 61
Source/MQTTnetServer/Startup.cs Прегледај датотеку

@@ -1,61 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace MQTTnetServer
{
/// <summary>
/// Web App Startup
/// </summary>
public class Startup
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="configuration"></param>
public Startup(IConfiguration configuration)
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables();
Configuration = builder.Build();
}

/// <summary>
/// Application Settings
/// </summary>
public IConfigurationRoot Configuration { get; }

/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseMvc();
}

/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
}
}

Loading…
Откажи
Сачувај