using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using StackExchange.Redis; using System.Text; using WebAppServer1.ApplicationDbContext; using WebAppServer1.Authentication; using WebAppServer1.Chat; //进度为简单聊天存储,私聊搜索用户等 var builder = WebApplication.CreateBuilder(args); // Add services to the container. // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddOpenApi(); //注册SignalR服务 builder.Services.AddSignalR(options => { options.MaximumReceiveMessageSize = 1024 * 1024 * 10; // 10MB }) .AddMessagePackProtocol(options => { options.SerializerOptions = MessagePack.MessagePackSerializerOptions.Standard .WithSecurity(MessagePack.MessagePackSecurity.UntrustedData); }); //连接并注册Redis服务 var redis = ConnectionMultiplexer.Connect("83.229.121.44:6378,password=redis_4GG7KG,defaultDatabase=5"); builder.Services.AddSingleton(redis); // 服务启动时清理 Redis //var _redis = scope.ServiceProvider.GetRequiredService(); var db = redis.GetDatabase(); var server = redis.GetServer(redis.GetEndPoints().First()); // 清理全局连接 await db.KeyDeleteAsync("AllConnections"); // 清理所有群组 foreach (var _key in server.Keys(pattern: "Group:*")) { await db.KeyDeleteAsync(_key); } //连接数据库 // 添加 DbContext 并使用 PostgreSQL builder.Services.AddDbContext(options => options.UseNpgsql(builder.Configuration.GetConnectionString("PostgresConnection"))); //配置跨域 builder.Services.AddCors(options => { options.AddPolicy("AllowVueApp", policy => { policy.WithOrigins("http://192.168.1.254:5173", "http://localhost:5173") // 前端地址 .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); //配置jwt // JWT 配置 var jwtSettings = builder.Configuration.GetSection("Jwt"); var keyString = jwtSettings["Key"] ?? throw new InvalidOperationException("JWT Key 未配置"); var key = Encoding.UTF8.GetBytes(keyString); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = jwtSettings["Issuer"], ValidAudience = jwtSettings["Audience"], IssuerSigningKey = new SymmetricSecurityKey(key) }; // 允许 SignalR 使用 JWT options.Events = new JwtBearerEvents { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/Chat")) { context.Token = accessToken; } return Task.CompletedTask; } }; }); builder.Services.AddScoped(); var app = builder.Build(); app.UseRouting(); //启用跨域配置 app.UseCors("AllowVueApp"); //启用jwt app.UseAuthentication(); app.UseAuthorization(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.MapOpenApi(); } //app.UseHttpsRedirection(); var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; //映射端点 app.MapHub("/Chat"); app.MapGet("/weatherforecast", () => { var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast ( DateOnly.FromDateTime(DateTime.Now.AddDays(index)), Random.Shared.Next(-20, 55), summaries[Random.Shared.Next(summaries.Length)] )) .ToArray(); return forecast; }) .WithName("GetWeatherForecast"); app.Run(); internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) { public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); }