25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

183 lines
6.4 KiB

  1. using System;
  2. using Microsoft.AspNetCore.Builder;
  3. using Microsoft.AspNetCore.Hosting;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.EntityFrameworkCore.Internal;
  6. using Microsoft.Extensions.Configuration;
  7. using Microsoft.Extensions.DependencyInjection;
  8. using Microsoft.OpenApi.Models;
  9. using Microsoft.Scripting.Utils;
  10. using MQTTnet.Server.Configuration;
  11. using MQTTnet.Server.Logging;
  12. using MQTTnet.Server.Mqtt;
  13. using MQTTnet.Server.Scripting;
  14. using MQTTnet.Server.Scripting.DataSharing;
  15. using Swashbuckle.AspNetCore.SwaggerUI;
  16. namespace MQTTnet.Server
  17. {
  18. public class Startup
  19. {
  20. public Startup(IConfiguration configuration)
  21. {
  22. var builder = new ConfigurationBuilder()
  23. .AddJsonFile("appsettings.json")
  24. .AddEnvironmentVariables();
  25. Configuration = builder.Build();
  26. }
  27. public IConfigurationRoot Configuration { get; }
  28. public void Configure(
  29. IApplicationBuilder application,
  30. IHostingEnvironment environment,
  31. MqttServerService mqttServerService,
  32. PythonScriptHostService pythonScriptHostService,
  33. DataSharingService dataSharingService,
  34. SettingsModel settings)
  35. {
  36. if (environment.IsDevelopment())
  37. {
  38. application.UseDeveloperExceptionPage();
  39. }
  40. else
  41. {
  42. application.UseHsts();
  43. }
  44. application.UseStaticFiles();
  45. application.UseHttpsRedirection();
  46. application.UseMvc();
  47. ConfigureWebSocketEndpoint(application, mqttServerService, settings);
  48. dataSharingService.Configure();
  49. pythonScriptHostService.Configure();
  50. mqttServerService.Configure();
  51. application.UseSwagger(o => o.RouteTemplate = "/api/{documentName}/swagger.json");
  52. application.UseSwaggerUI(o =>
  53. {
  54. o.RoutePrefix = "api";
  55. o.DocumentTitle = "MQTTnet.Server API";
  56. o.SwaggerEndpoint("/api/v1/swagger.json", "MQTTnet.Server API v1");
  57. o.DisplayRequestDuration();
  58. o.DocExpansion(DocExpansion.List);
  59. o.DefaultModelRendering(ModelRendering.Model);
  60. });
  61. }
  62. public void ConfigureServices(IServiceCollection services)
  63. {
  64. services.AddMvc()
  65. .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
  66. .AddJsonOptions(options =>
  67. {
  68. options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
  69. });
  70. services.AddSingleton(ReadSettings());
  71. services.AddSingleton<PythonIOStream>();
  72. services.AddSingleton<PythonScriptHostService>();
  73. services.AddSingleton<DataSharingService>();
  74. services.AddSingleton<MqttNetLoggerWrapper>();
  75. services.AddSingleton<CustomMqttFactory>();
  76. services.AddSingleton<MqttServerService>();
  77. services.AddSingleton<MqttServerStorage>();
  78. services.AddSingleton<MqttClientConnectedHandler>();
  79. services.AddSingleton<MqttClientDisconnectedHandler>();
  80. services.AddSingleton<MqttClientSubscribedTopicHandler>();
  81. services.AddSingleton<MqttClientUnsubscribedTopicHandler>();
  82. services.AddSingleton<MqttConnectionValidator>();
  83. services.AddSingleton<MqttSubscriptionInterceptor>();
  84. services.AddSingleton<MqttApplicationMessageInterceptor>();
  85. services.AddSwaggerGen(c =>
  86. {
  87. c.DescribeAllEnumsAsStrings();
  88. c.SwaggerDoc("v1", new OpenApiInfo
  89. {
  90. Title = "MQTTnet.Server API",
  91. Version = "v1",
  92. Description = "The public API for the MQTT broker MQTTnet.Server.",
  93. License = new OpenApiLicense
  94. {
  95. Name = "MIT",
  96. Url = new Uri("https://github.com/chkr1011/MQTTnet/blob/master/README.md")
  97. },
  98. Contact = new OpenApiContact
  99. {
  100. Name = "MQTTnet.Server",
  101. Email = string.Empty,
  102. Url = new Uri("https://github.com/chkr1011/MQTTnet")
  103. },
  104. });
  105. });
  106. }
  107. private SettingsModel ReadSettings()
  108. {
  109. var settings = new Configuration.SettingsModel();
  110. Configuration.Bind("MQTT", settings);
  111. return settings;
  112. }
  113. private static void ConfigureWebSocketEndpoint(
  114. IApplicationBuilder application,
  115. MqttServerService mqttServerService,
  116. SettingsModel settings)
  117. {
  118. if (settings?.WebSocketEndPoint?.Enabled != true)
  119. {
  120. return;
  121. }
  122. if (string.IsNullOrEmpty(settings.WebSocketEndPoint.Path))
  123. {
  124. return;
  125. }
  126. var webSocketOptions = new WebSocketOptions
  127. {
  128. KeepAliveInterval = TimeSpan.FromSeconds(settings.WebSocketEndPoint.KeepAliveInterval),
  129. ReceiveBufferSize = settings.WebSocketEndPoint.ReceiveBufferSize
  130. };
  131. if (settings.WebSocketEndPoint.AllowedOrigins?.Any() == true)
  132. {
  133. webSocketOptions.AllowedOrigins.AddRange(settings.WebSocketEndPoint.AllowedOrigins);
  134. }
  135. application.UseWebSockets(webSocketOptions);
  136. application.Use(async (context, next) =>
  137. {
  138. if (context.Request.Path == settings.WebSocketEndPoint.Path)
  139. {
  140. if (context.WebSockets.IsWebSocketRequest)
  141. {
  142. using (var webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false))
  143. {
  144. await mqttServerService.RunWebSocketConnectionAsync(webSocket, context).ConfigureAwait(false);
  145. }
  146. }
  147. else
  148. {
  149. context.Response.StatusCode = 400;
  150. }
  151. }
  152. else
  153. {
  154. await next().ConfigureAwait(false);
  155. }
  156. });
  157. }
  158. }
  159. }