Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 

224 rindas
8.0 KiB

  1. using Microsoft.AspNetCore.Authentication;
  2. using Microsoft.AspNetCore.Builder;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.Extensions.Configuration;
  5. using Microsoft.Extensions.DependencyInjection;
  6. using Microsoft.Net.Http.Headers;
  7. using Microsoft.OpenApi.Models;
  8. using Microsoft.Scripting.Utils;
  9. using MQTTnet.AspNetCore;
  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 Newtonsoft.Json.Converters;
  16. using Swashbuckle.AspNetCore.SwaggerUI;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Linq;
  20. using System.Net;
  21. namespace MQTTnet.Server.Web
  22. {
  23. public class Startup
  24. {
  25. public Startup(IConfiguration configuration)
  26. {
  27. var builder = new ConfigurationBuilder()
  28. .AddJsonFile("appsettings.json")
  29. .AddEnvironmentVariables();
  30. Configuration = builder.Build();
  31. }
  32. public IConfigurationRoot Configuration { get; }
  33. public void Configure(
  34. IApplicationBuilder application,
  35. MqttServerService mqttServerService,
  36. PythonScriptHostService pythonScriptHostService,
  37. DataSharingService dataSharingService,
  38. MqttSettingsModel mqttSettings)
  39. {
  40. application.UseDefaultFiles();
  41. application.UseStaticFiles();
  42. application.UseHsts();
  43. application.UseRouting();
  44. application.UseCors(x => x
  45. .AllowAnyOrigin()
  46. .AllowAnyMethod()
  47. .AllowAnyHeader());
  48. application.UseAuthentication();
  49. application.UseAuthorization();
  50. application.UseEndpoints(endpoints =>
  51. {
  52. endpoints.MapControllers();
  53. });
  54. ConfigureWebSocketEndpoint(application, mqttServerService, mqttSettings);
  55. dataSharingService.Configure();
  56. pythonScriptHostService.Configure();
  57. mqttServerService.Configure();
  58. application.UseSwagger(o => o.RouteTemplate = "/api/{documentName}/swagger.json");
  59. application.UseSwaggerUI(o =>
  60. {
  61. o.RoutePrefix = "api";
  62. o.DocumentTitle = "MQTTnet.Server API";
  63. o.SwaggerEndpoint("/api/v1/swagger.json", "MQTTnet.Server API v1");
  64. o.DisplayRequestDuration();
  65. o.DocExpansion(DocExpansion.List);
  66. o.DefaultModelRendering(ModelRendering.Model);
  67. });
  68. }
  69. public void ConfigureServices(IServiceCollection services)
  70. {
  71. services.AddCors();
  72. services.AddControllers();
  73. services.AddMvc()
  74. .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
  75. .AddNewtonsoftJson(o =>
  76. {
  77. o.SerializerSettings.Converters.Add(new StringEnumConverter());
  78. });
  79. ReadMqttSettings(services);
  80. services.AddSingleton<PythonIOStream>();
  81. services.AddSingleton<PythonScriptHostService>();
  82. services.AddSingleton<DataSharingService>();
  83. services.AddSingleton<MqttNetLoggerWrapper>();
  84. services.AddSingleton<CustomMqttFactory>();
  85. services.AddSingleton<MqttServerService>();
  86. services.AddSingleton<MqttServerStorage>();
  87. services.AddSingleton<MqttClientConnectedHandler>();
  88. services.AddSingleton<MqttClientDisconnectedHandler>();
  89. services.AddSingleton<MqttClientSubscribedTopicHandler>();
  90. services.AddSingleton<MqttClientUnsubscribedTopicHandler>();
  91. services.AddSingleton<MqttServerConnectionValidator>();
  92. services.AddSingleton<MqttSubscriptionInterceptor>();
  93. services.AddSingleton<MqttUnsubscriptionInterceptor>();
  94. services.AddSingleton<MqttApplicationMessageInterceptor>();
  95. services.AddSwaggerGen(c =>
  96. {
  97. var securityScheme = new OpenApiSecurityScheme
  98. {
  99. Scheme = "Basic",
  100. Name = HeaderNames.Authorization,
  101. Type = SecuritySchemeType.Http,
  102. In = ParameterLocation.Header
  103. };
  104. c.AddSecurityDefinition("Swagger", securityScheme);
  105. c.AddSecurityRequirement(new OpenApiSecurityRequirement
  106. {
  107. [securityScheme] = new List<string>()
  108. });
  109. c.SwaggerDoc("v1", new OpenApiInfo
  110. {
  111. Title = "MQTTnet.Server API",
  112. Version = "v1",
  113. Description = "The public API for the MQTT broker MQTTnet.Server.",
  114. License = new OpenApiLicense
  115. {
  116. Name = "MIT",
  117. Url = new Uri("https://github.com/chkr1011/MQTTnet/blob/master/README.md")
  118. },
  119. Contact = new OpenApiContact
  120. {
  121. Name = "MQTTnet.Server",
  122. Email = string.Empty,
  123. Url = new Uri("https://github.com/chkr1011/MQTTnet")
  124. },
  125. });
  126. });
  127. services.AddAuthentication("Basic")
  128. .AddScheme<AuthenticationSchemeOptions, AuthenticationHandler>("Basic", null)
  129. .AddCookie();
  130. }
  131. void ReadMqttSettings(IServiceCollection services)
  132. {
  133. var mqttSettings = new MqttSettingsModel();
  134. Configuration.Bind("MQTT", mqttSettings);
  135. services.AddSingleton(mqttSettings);
  136. var scriptingSettings = new ScriptingSettingsModel();
  137. Configuration.Bind("Scripting", scriptingSettings);
  138. services.AddSingleton(scriptingSettings);
  139. }
  140. static void ConfigureWebSocketEndpoint(
  141. IApplicationBuilder application,
  142. MqttServerService mqttServerService,
  143. MqttSettingsModel mqttSettings)
  144. {
  145. if (mqttSettings?.WebSocketEndPoint?.Enabled != true)
  146. {
  147. return;
  148. }
  149. if (string.IsNullOrEmpty(mqttSettings.WebSocketEndPoint.Path))
  150. {
  151. return;
  152. }
  153. var webSocketOptions = new WebSocketOptions
  154. {
  155. KeepAliveInterval = TimeSpan.FromSeconds(mqttSettings.WebSocketEndPoint.KeepAliveInterval),
  156. ReceiveBufferSize = mqttSettings.WebSocketEndPoint.ReceiveBufferSize
  157. };
  158. if (mqttSettings.WebSocketEndPoint.AllowedOrigins?.Any() == true)
  159. {
  160. webSocketOptions.AllowedOrigins.AddRange(mqttSettings.WebSocketEndPoint.AllowedOrigins);
  161. }
  162. application.UseWebSockets(webSocketOptions);
  163. application.Use(async (context, next) =>
  164. {
  165. if (context.Request.Path == mqttSettings.WebSocketEndPoint.Path)
  166. {
  167. if (context.WebSockets.IsWebSocketRequest)
  168. {
  169. string subProtocol = null;
  170. if (context.Request.Headers.TryGetValue("Sec-WebSocket-Protocol", out var requestedSubProtocolValues))
  171. {
  172. subProtocol = MqttSubProtocolSelector.SelectSubProtocol(requestedSubProtocolValues);
  173. }
  174. using (var webSocket = await context.WebSockets.AcceptWebSocketAsync(subProtocol).ConfigureAwait(false))
  175. {
  176. await mqttServerService.RunWebSocketConnectionAsync(webSocket, context).ConfigureAwait(false);
  177. }
  178. }
  179. else
  180. {
  181. context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
  182. }
  183. }
  184. else
  185. {
  186. await next().ConfigureAwait(false);
  187. }
  188. });
  189. }
  190. }
  191. }