123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- using Hangfire;
- using Hangfire.Redis.StackExchange;
- using Microsoft.AspNetCore.Authentication.JwtBearer;
- using Microsoft.Extensions.DependencyInjection.Extensions;
- using Microsoft.IdentityModel.Tokens;
- using System.IdentityModel.Tokens.Jwt;
- using TEAMModelOS.SDK.DI;
- using TEAMModelOS.SDK;
- using HTEX.Complex.Services;
- using HTEX.Complex.Services.MQTT;
- using MathNet.Numerics;
- using MQTTnet.AspNetCore;
- using MQTTnet.Server;
- using Microsoft.Extensions.Options;
- using System.Threading;
- using Microsoft.Extensions.Logging;
- using System.Text.Json;
- using Microsoft.Extensions.Hosting;
- using MQTTnet.AspNetCore.Routing;
- using Microsoft.AspNetCore.Builder;
- using Microsoft.AspNetCore.Hosting.Server;
- using Microsoft.AspNetCore.Hosting.Server.Features;
- using System.Security.Policy;
- using System.Net.Http;
- using TEAMModelOS.SDK.DI.Device;
- using Serilog;
- namespace HTEX.Complex
- {
- public class Program
- {
- public static void Main(string[] args)
- {
-
- var builder = WebApplication.CreateBuilder(args);
- //防止编译后的appsettings.json 文件内容,在重新部署的时候,因为不同的环境导致被覆盖的问题,
- //所以在正式环境中指定appsettings-prod.json一个本地开发环境不存在的文件,以达到不会被覆盖的问题,
- //即使在生产环境中未配置appsettings-prod.json 也不影响启动,因为会按照appsettings.json的配置启动
- #if !DEBUG
- builder.Host.ConfigureAppConfiguration((context, config) => {
- config.SetBasePath(Directory.GetCurrentDirectory());
- config.AddJsonFile("appsettings-prod.json", optional: true, reloadOnChange: true);
- });
- #endif
- Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console(outputTemplate: "{Timestamp:HH:mm:ss.fff zzz} [{Level:u3}] ({ThreadId}) {Message}{NewLine}{Exception}")
- .WriteTo.File("logs/log-.log", rollingInterval: RollingInterval.Day).CreateLogger();
- builder.Host.UseSerilog();
- //builder.WebHost.ConfigureKestrel(options =>
- //{
- // //options.ListenAnyIP(4001, options => {
- // // // options.UseHttps("Crt/iteden.pfx", "iteden");
- // //});
- // options.ListenAnyIP(1883, options => { options.UseMqtt();/*options.UseHttps("Crt/iteden.pfx", "iteden");*/ });
- // options.ListenAnyIP(1884, options => { options.UseMqtt();/* options.UseHttps("Configs/Crt/iteden.pfx", "iteden"); */}); // Default HTTP pipeline
- //});
- //builder.WebHost.ConfigureKestrel(options =>
- //{
- // //options.ListenAnyIP(4001, options => {
- // // // options.UseHttps("Crt/iteden.pfx", "iteden");
- // //});
- // options.ListenAnyIP(1883, options => { options.UseMqtt();/*options.UseHttps("Crt/iteden.pfx", "iteden");*/ });
- // options.ListenAnyIP(1884, options => { options.UseMqtt();/* options.UseHttps("Configs/Crt/iteden.pfx", "iteden"); */}); // Default HTTP pipeline
- //});
- // Add services to the container.
- JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
- builder.Services.AddAuthentication(options => options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme)
- .AddJwtBearer(options => //AzureADJwtBearer
- {
- //options.SaveToken = true; //驗證令牌由服務器生成才有效,不適用於服務重啟或分布式架構
- options.Authority ="https://login.chinacloudapi.cn/4807e9cf-87b8-4174-aa5b-e76497d7392b/v2.0";// builder.Configuration["Option:Authority"];
- options.Audience = "72643704-b2e7-4b26-b881-bd5865e7a7a5";//builder.Configuration["Option:Audience"];
- options.RequireHttpsMetadata = true;
- options.TokenValidationParameters = new TokenValidationParameters
- {
- RoleClaimType = "roles",
- //ValidAudiences = new string[] { builder.Configuration["Option:Audience"], $"api://{builder.Configuration["Option:Audience"]}" }
- ValidAudiences = new string[] { "72643704-b2e7-4b26-b881-bd5865e7a7a5", $"api://72643704-b2e7-4b26-b881-bd5865e7a7a5" }
- };
- options.Events = new JwtBearerEvents();
- //下列事件有需要紀錄則打開
- //options.Events.OnMessageReceived = async context => { await Task.FromResult(0); };
- //options.Events.OnForbidden = async context => { await Task.FromResult(0); };
- //options.Events.OnChallenge = async context => { await Task.FromResult(0); };
- //options.Events.OnAuthenticationFailed = async context => { await Task.FromResult(0); };
- options.Events.OnTokenValidated = async context =>
- {
- if (!context.Principal.Claims.Any(x => x.Type.Equals("http://schemas.microsoft.com/identity/claims/scope")) //ClaimConstants.Scope
- && !context.Principal.Claims.Any(y => y.Type.Equals("roles"))) //ClaimConstants.Roles //http://schemas.microsoft.com/ws/2008/06/identity/claims/role
- {
- //TODO 需處理額外授權非角色及範圍的訪問異常紀錄
- throw new UnauthorizedAccessException("Neither scope or roles claim was found in the bearer token.");
- }
- await Task.FromResult(0);
- };
- });
- builder.Services.AddControllers();
-
- // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
- builder.Services.AddEndpointsApiExplorer();
- //builder.Services.AddSwaggerGen();
- builder.Services.AddHttpClient();
- string? StorageConnectionString = builder.Configuration.GetValue<string>("Azure:Storage:ConnectionString");
- string? RedisConnectionString = builder.Configuration.GetValue<string>("Azure:Redis:ConnectionString");
- //Storage
- builder.Services.AddAzureStorage(StorageConnectionString, "Default");
- //Redis
- builder.Services.AddAzureRedis(RedisConnectionString, "Default");
- builder.Services.AddSignalR();
- builder.Services.AddHttpContextAccessor();
- builder.Services.AddHttpClient<DingDing>();
- string path = $"{builder.Environment.ContentRootPath}/JsonFiles";
- builder.Services.TryAddSingleton(new Region2LongitudeLatitudeTranslator(path));
- builder.Services.AddIPSearcher(path);
- builder.Services.AddSingleton<CoreDevice>();
- builder.Services.AddCors(options =>
- {
- options.AddDefaultPolicy(
- builder =>
- {
- builder.AllowAnyOrigin()
- .AllowAnyHeader()
- .AllowAnyMethod();
- });
- });
- builder.Services.AddControllersWithViews();
- //MQTT 服务端API 发送消息到MQTT客户端 https://www.cnblogs.com/weskynet/p/16441219.html
- #region MQTT配置
- builder.Services.AddSingleton<MQTTEvents>();
- builder.Services.AddSingleton(new JsonSerializerOptions(JsonSerializerDefaults.Web));
- builder.Services.AddHostedMqttServerWithServices(x =>
- {
- x.WithDefaultEndpoint()
- .WithConnectionBacklog(1000)
- .WithPersistentSessions(true).WithKeepAlive()
- .WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(30));
- }).AddMqttConnectionHandler().AddConnections().AddMqttControllers();
- #endregion
- var app = builder.Build();
-
- // Configure the HTTP request pipeline.
- if (!app.Environment.IsDevelopment())
- {
- app.UseExceptionHandler("/Home/Error");
- // 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.UseRouting();
- app.UseCors(); //使用跨域設定
- app.UseAuthentication();
- app.UseAuthorization();
- app.MapControllers();
- app.MapHub<SignalRScreenServerHub>("/signalr/screen").RequireCors("any");
- app.MapConnectionHandler<MqttConnectionHandler>("/mqtt", opts => opts.WebSockets.SubProtocolSelector = protocolList => protocolList.FirstOrDefault() ?? string.Empty);
- var events = app.Services.GetRequiredService<MQTTEvents>();
- app.UseMqttServer(server =>
- {
- server.WithAttributeRouting(app.Services, allowUnmatchedRoutes: false);
- server.ClientSubscribedTopicAsync+=events._mqttServer_ClientSubscribedTopicAsync;// 客户端订阅主题事件
- server.StoppedAsync+=events._mqttServer_StoppedAsync;// 关闭后事件
- server.ValidatingConnectionAsync+=events._mqttServer_ValidatingConnectionAsync; // 用户名和密码验证有关
- server.InterceptingPublishAsync+=events._mqttServer_InterceptingPublishAsync;// 消息接收事件
- server.StartedAsync+=events._mqttServer_StartedAsync;// 启动后事件
- server.ClientUnsubscribedTopicAsync+=events._mqttServer_ClientUnsubscribedTopicAsync;// 客户端取消订阅事件
- server.ApplicationMessageNotConsumedAsync+=events._mqttServer_ApplicationMessageNotConsumedAsync; // 消息接收事件,应用程序消息未使用
- server.ClientDisconnectedAsync+=events._mqttServer_ClientDisconnectedAsync;// 客户端关闭事件
- server.ClientConnectedAsync+=events._mqttServer_ClientConnectedAsync;//客户端连接事件
- //server.InterceptingClientEnqueueAsync += events._mqttServer_InterceptingClientEnqueueAsync;//拦截客户端排队
- //server.ClientAcknowledgedPublishPacketAsync += events._mqttServer_ClientAcknowledgedPublishPacketAsync;//已确认发布数据包
- });
- app.Run();
-
- }
- }
- }
|