Files
BuYuHouDuan/FishGameSrc/FishGameHost/Program.cs
T
wz1531 d083d8524b 补回 swagger(Swashbuckle 6.6.2 + XML 注释)、socket.html 入库、固化本机构建与服务器替换脚本
- Directory.Build.props: 生成 XML 注释供 Swagger 展示中文说明
- AdminHost/FishGameHost: 接入 Swashbuckle,路由 adminswagger / roomswagger
- 后台前端 config.js 改为同源相对地址,适配反向代理
- socket.html(SignalR 协议文档)纳入仓库
- deploy/: 本机构建(容器内编译,规避杀软)、服务器替换脚本、Nginx 配置
2026-10-18 17:28:45 +08:00

234 lines
7.1 KiB
C#

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Common;
using Common.Request;
using CommonService;
using DotNetCore.CAP;
using FishGameHost.Extension;
using FishGameHost.Middleware;
using FishGameService.Config;
using FishGameService.Hubs;
using FishGameService.Subscribers;
using JWTHelper;
using MessagePack;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using MongoRepository;
using MongoRepository.Config;
using NLog.Extensions.Logging;
using NLog.Web;
using RedisHelper;
using RedisService;
using UserDomain.Entity;
using SharpAbp.Infrastructure.Api.Middleware;
using StackExchange.Redis;
using System.Text.Json;
using UserService;
using static Common.Utils.DateTimeTools;
Environment.SetEnvironmentVariable("SERVICE_NAME",
Environment.GetEnvironmentVariable("SERVICE_NAME")
?? System.Reflection.Assembly.GetEntryAssembly()?.GetName().Name
?? "FishGameHost");
Environment.SetEnvironmentVariable("INSTANCE_ID",
Environment.GetEnvironmentVariable("INSTANCE_ID") ?? "default");
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
string instanceId = Environment.GetEnvironmentVariable("INSTANCE_ID") ?? "Unknown";
builder.Services.AddSingleton(sp => new AppInstanceId { Id = instanceId });
builder.Services.AddControllers();
builder.Logging.AddNLog();
builder.Host.UseNLog();
builder.Configuration.AddJsonFile(Path.Combine("Config", "system.json"), optional: true);
builder.Services.Configure<MongoDbSettings>(builder.Configuration.GetSection(nameof(MongoDbSettings)));
builder.Services.AddSingleton<IMongoDbSettings>(sp => sp.GetRequiredService<IOptions<MongoDbSettings>>().Value);
string redisConn = builder.Configuration.GetConnectionString("Redis");
if (string.IsNullOrWhiteSpace(redisConn))
{
var redisSection = builder.Configuration.GetSection("RedisConfig");
var host = redisSection["Host"];
var port = redisSection["Port"] ?? "6379";
var password = redisSection["Password"];
var database = redisSection["Database"] ?? "0";
if (string.IsNullOrWhiteSpace(host))
{
throw new InvalidOperationException("未找到 Redis 配置:请在 ConnectionStrings:Redis 或 RedisConfig 节中配置 Redis 地址。");
}
redisConn = $"{host}:{port}";
if (!string.IsNullOrEmpty(password))
redisConn += $",password={password}";
if (!string.IsNullOrEmpty(database))
redisConn += $",defaultDatabase={database}";
}
var tempLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); });
var tempLogger = tempLoggerFactory.CreateLogger("Startup");
builder.Services.AddSingleton<IConnectionMultiplexer>(sp =>
{
return ConnectionMultiplexer.Connect(redisConn);
});
builder.Services.AddSignalR(hubOptions =>
{
hubOptions.MaximumReceiveMessageSize = 64 * 1024;
hubOptions.StreamBufferCapacity = 512;
hubOptions.ClientTimeoutInterval = TimeSpan.FromSeconds(60);
hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(5);
hubOptions.AddFilter<MovementFilter>();
hubOptions.AddFilter<HubExceptionFilter>();
})
.AddJsonProtocol();
builder.Services.Configure<FormOptions>(x =>
{
x.MultipartBodyLengthLimit = 1024 * 1024 * 16;
});
builder.Services.AddMemoryCache();
builder.Services.AddControllers().AddJsonOptions(configure =>
{
configure.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
});
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<IHubSend<FishGameHub>, HubSend<FishGameHub>>();
builder.Services.AddSingleton<IRequestApi, RequestApi>();
builder.Services.AddAutoMapper(typeof(AutoMapperConfig));
builder.Services.AddHealthChecks()
.AddCheck("self", () => HealthCheckResult.Healthy(), tags: new[] { "self" });
builder.Services.AddCors(options =>
{
options.AddPolicy("Cors", policy =>
{
policy
.SetIsOriginAllowed(_ => true)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
#region jwt
builder.Services.AddCustomJwt(builder.Configuration);
#endregion
#region redishelper
builder.Services.AddRedisCacheSingleton(builder.Configuration);
#endregion
builder.Services.Configure<BulletConfig>(builder.Configuration.GetSection("BulletConfig"));
builder.Services.AddSingleton<BulletConfig>(sp => sp.GetRequiredService<IOptions<BulletConfig>>().Value);
#region Swagger
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
{
Title = "FishGameHost",
Description = "捕鱼游戏接口",
Version = "v1"
});
// 加载各项目生成的 XML 注释,用于展示接口的中文说明
foreach (var xml in System.IO.Directory.GetFiles(AppContext.BaseDirectory, "*.xml"))
{
try { c.IncludeXmlComments(xml, true); } catch { }
}
});
#endregion
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule<AutofacModule>();
});
#region Cap
builder.Services.AddTransient<ICapSubscribe, PlayerFactorSubscriber>();
builder.Services.AddTransient<ICapSubscribe, LoginBindSubscriber>();
builder.Services.AddTransient<ICapSubscribe, BackgroundAssetSubscriber>();
builder.Services.AddTransient<ICapSubscribe, TempSpawnFishSubscriber>();
builder.Services.AddCap(builder.Configuration);
#endregion
builder.Services.AddHostedService<FishGameHost.Services.GlobalBroadcastSubscriber>();
builder.Services.AddHostedService<FishGameService.Services.RobotKillAnnounceService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
}
#region Swagger
app.UseSwagger(c => c.RouteTemplate = "roomswagger/{documentName}/swagger.json");
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "roomswagger";
c.SwaggerEndpoint("v1/swagger.json", "FishGameHost v1");
});
#endregion
app.UseApiLogging();
app.UseRouting();
app.UseGlobalExceptionHandler();
app.UseStaticFiles();
app.UseCors("Cors");
app.UseAuthentication();
app.UseAuthorization();
app.MapHub<FishGameHub>("/fishinghub", options =>
{
options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
});
app.MapControllers();
app.MapHealthChecks("/health", new HealthCheckOptions
{
Predicate = _ => true,
ResponseWriter = async (context, report) =>
{
context.Response.ContentType = "application/json";
var result = new
{
status = report.Status.ToString(),
checks = report.Entries.Select(e => new
{
name = e.Key,
status = e.Value.Status.ToString(),
description = e.Value.Description,
duration = e.Value.Duration.TotalMilliseconds
}),
totalDuration = report.TotalDuration.TotalMilliseconds
};
await context.Response.WriteAsync(JsonSerializer.Serialize(result));
}
});
app.Run();