添加项目文件。
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
**/.classpath
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
!**/.gitignore
|
||||
!.git/HEAD
|
||||
!.git/config
|
||||
!.git/packed-refs
|
||||
!.git/refs/heads/**
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"urls": "http://*:8004",
|
||||
|
||||
|
||||
"AllowedHosts": "*",
|
||||
"JwtConfig": {
|
||||
"TokenKey": "token",
|
||||
"Issuer": "admin",
|
||||
"Audience": "", // "Audience": "",
|
||||
"SecretKey": "henanhuashengchongwuyouxiangongsikejizhongxin",
|
||||
"ValidateIssuer": false,
|
||||
"ValidateAudience": false,
|
||||
"ValidateIssuerSigningKey": false,
|
||||
"ValidateLifetime": false
|
||||
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"PgSqlConnection": "host=localhost;database=data_0524;user id=data_0524;password=123456;"
|
||||
},
|
||||
"CapConfig": {
|
||||
"Host": "localhost",
|
||||
"UserName": "admin",
|
||||
"Password": "123456",
|
||||
"VirtualHost": "/",
|
||||
"PGLogHost": "host=localhost;database=data_0524;user id=data_0524;password=123456;"
|
||||
},
|
||||
"RedisConfig": {
|
||||
"Host": "localhost",
|
||||
"Port": 6378,
|
||||
"UserName": "",
|
||||
"Password": "123456",
|
||||
"Database": 2
|
||||
},
|
||||
"MongoDbSettings": {
|
||||
"username": "root",
|
||||
"password": "root23456",
|
||||
"ServerUrl": "mongodb://localhost:27018/?authSource=admin"
|
||||
},
|
||||
"WXConfig": {
|
||||
"AppId": "wxceab9ce5b4474219",
|
||||
"Secret": "5a291d7b295c76da579611da3f83e059",
|
||||
"Url": "https://api.weixin.qq.com"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using DotNetCore.CAP.Messages;
|
||||
using FishRoomService.MQ;
|
||||
|
||||
namespace FishRoomHost.Extension
|
||||
{
|
||||
public static class CapExtension
|
||||
{
|
||||
public static IServiceCollection AddCap(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddCap(x =>
|
||||
{
|
||||
x.UseDashboard();
|
||||
x.UseRabbitMQ(rb =>
|
||||
{
|
||||
rb.HostName = configuration["CapConfig:Host"];
|
||||
rb.UserName = configuration["CapConfig:UserName"];
|
||||
rb.Password = configuration["CapConfig:Password"];
|
||||
rb.VirtualHost = configuration["CapConfig:VirtualHost"];
|
||||
rb.ExchangeName = "cap.exchange";
|
||||
});
|
||||
x.UsePostgreSql(op =>
|
||||
{
|
||||
op.ConnectionString = configuration["CapConfig:PGLogHost"];
|
||||
op.Schema = "public";
|
||||
});
|
||||
|
||||
|
||||
|
||||
x.SucceedMessageExpiredAfter = 7 * 24 * 3600;
|
||||
x.FailedRetryCount = 5;
|
||||
x.FailedRetryInterval = 10;
|
||||
x.FailedThresholdCallback = ObjFailedThresholdCallback;
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
services.AddTransient<IRoomMQService, RoomMQService>();
|
||||
return services;
|
||||
}
|
||||
|
||||
private static async void ObjFailedThresholdCallback(FailedInfo failed)
|
||||
{
|
||||
var exception = failed.Message.Headers["cap-exception"] ?? string.Empty;
|
||||
var name = failed.Message.GetName();
|
||||
if (failed.MessageType == MessageType.Publish)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="8.0.0" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.7.4" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="6.1.2" />
|
||||
<PackageReference Include="Autofac" Version="8.3.0" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
|
||||
<PackageReference Include="AutoMapper" Version="14.0.0" />
|
||||
<PackageReference Include="DotNetCore.CAP" Version="8.3.4" />
|
||||
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="8.3.4" />
|
||||
<PackageReference Include="DotNetCore.CAP.PostgreSql" Version="8.3.4" />
|
||||
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="8.3.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="8.0.17" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\FishRoomService\FishRoomService.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\CommonInfrastructure\CommonInfrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\SharpAbp.Infrastructure.Api\SharpAbp.Infrastructure.Api.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\nlog.config" Link="nlog.config" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
|
||||
<None Update="docker-compose.yaml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Dockerfile">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,169 @@
|
||||
|
||||
using System.Text;
|
||||
using Common;
|
||||
using CommonDomain;
|
||||
using CommonService;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace FishRoomHost.Middleware
|
||||
{
|
||||
public class ApiLoggingMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ILogger<ApiLoggingMiddleware> _logger;
|
||||
private readonly IApiLogService _apiLogService;
|
||||
|
||||
public ApiLoggingMiddleware(RequestDelegate next, ILogger<ApiLoggingMiddleware> logger, IApiLogService apiLogService)
|
||||
{
|
||||
_next = next;
|
||||
_logger = logger;
|
||||
_apiLogService = apiLogService;
|
||||
}
|
||||
public async Task Invoke(HttpContext httpContext)
|
||||
{
|
||||
var request = httpContext.Request;
|
||||
if (request.Path.StartsWithSegments(new PathString("/api")) && request.Method.ToLower() != "options")
|
||||
{
|
||||
var requestTime = DateTime.Now;
|
||||
var requestBodyContent = string.Empty;
|
||||
var originalRequest = httpContext.Response.Body;
|
||||
if (request.Method == "POST")
|
||||
{
|
||||
request.EnableBuffering();
|
||||
requestBodyContent = await new StreamReader(request.Body).ReadToEndAsync();
|
||||
request.Body.Position = 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (var responseBody = new MemoryStream())
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
response.Body = responseBody;
|
||||
await _next(httpContext);
|
||||
string responseBodyContent = null;
|
||||
responseBodyContent = await FormatResponse(response);
|
||||
await responseBody.CopyToAsync(originalRequest);
|
||||
|
||||
string token = string.Empty, version = string.Empty, userAgent = string.Empty, source = string.Empty, deviceId = string.Empty, device = string.Empty, ip = string.Empty,sign=string.Empty;
|
||||
if (httpContext.Request != null && httpContext.Request.Headers != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Token"]))
|
||||
{
|
||||
token = httpContext.Request.Headers["Token"] + ""; }
|
||||
|
||||
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Version"]))
|
||||
{
|
||||
version = httpContext.Request.Headers["Version"] + "";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(httpContext.Request.Headers["User-Agent"]))
|
||||
{
|
||||
userAgent = httpContext.Request.Headers["User-Agent"] + "";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Source"]))
|
||||
{
|
||||
source = httpContext.Request.Headers["Source"] + "";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(httpContext.Request.Headers["DeviceId"]))
|
||||
{
|
||||
deviceId = httpContext.Request.Headers["DeviceId"] + "";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Device"]))
|
||||
{
|
||||
device = httpContext.Request.Headers["Device"] + "";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Ip"]))
|
||||
{
|
||||
ip = httpContext.Request.Headers["Ip"] + "";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Sign"]))
|
||||
{
|
||||
sign = httpContext.Request.Headers["Sign"] + "";
|
||||
}
|
||||
}
|
||||
string allResponseContent = responseBodyContent;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(responseBodyContent))
|
||||
{
|
||||
BaseResponse<object> baseResponse = JsonConvert.DeserializeObject<BaseResponse<object>>(responseBodyContent);
|
||||
if (baseResponse != null && baseResponse.Data != null)
|
||||
{
|
||||
baseResponse.Data = null;
|
||||
}
|
||||
responseBodyContent = JsonConvert.SerializeObject(baseResponse);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "API响应日志脱敏序列化失败 path={Path}", request.Path);
|
||||
}
|
||||
var now = DateTime.Now;
|
||||
var apilog = new ApiLog()
|
||||
{
|
||||
requestTime = now,
|
||||
accessToken = token,
|
||||
clientIP = httpContext.Connection.RemoteIpAddress.ToString(),
|
||||
consumeTime = (DateTime.Now - requestTime).Milliseconds,
|
||||
requestHead= JsonConvert.SerializeObject(httpContext.Request.Headers),
|
||||
requestUrl = request.Path,
|
||||
requestMethod = request.Method.ToLower(),
|
||||
requestQuery = request.QueryString.ToString(),
|
||||
requestBody = requestBodyContent,
|
||||
httpStatus = httpContext.Response.StatusCode,
|
||||
responseBody = responseBodyContent,
|
||||
userAgent = userAgent,
|
||||
device= device,
|
||||
deviceId= deviceId,
|
||||
ip=ip,
|
||||
source=source,
|
||||
version=version,
|
||||
sign=sign
|
||||
};
|
||||
await _apiLogService.InsertOneAsync(apilog);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "API日志记录失败 path={Path}", request.Path);
|
||||
}
|
||||
finally
|
||||
{
|
||||
httpContext.Response.Body = originalRequest;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next(httpContext);
|
||||
}
|
||||
}
|
||||
private async Task<string> FormatRequest(Microsoft.AspNetCore.Http.HttpRequest request)
|
||||
{
|
||||
var body = request.Body;
|
||||
request.EnableBuffering();
|
||||
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
|
||||
await request.Body.ReadAsync(buffer, 0, buffer.Length);
|
||||
var bodyAsText = Encoding.UTF8.GetString(buffer);
|
||||
request.Body = body;
|
||||
return bodyAsText;
|
||||
}
|
||||
|
||||
private async Task<string> FormatResponse(HttpResponse response)
|
||||
{
|
||||
response.Body.Seek(0, SeekOrigin.Begin);
|
||||
string text = await new StreamReader(response.Body).ReadToEndAsync();
|
||||
response.Body.Seek(0, SeekOrigin.Begin);
|
||||
//return $"{response.StatusCode}: {text}";
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApiLoggingMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseApiLogging(this IApplicationBuilder app)
|
||||
{
|
||||
return app.UseMiddleware<ApiLoggingMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
|
||||
using Autofac;
|
||||
using CommonService;
|
||||
using FishRoomService.RoomService;
|
||||
using MongoRepository;
|
||||
|
||||
namespace FishRoomHost.Middleware
|
||||
{
|
||||
public class AutofacModule : Module
|
||||
{
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterGeneric(typeof(MongoBaseRepository<>)).As(typeof(IMongoBaseRepository<>)).InstancePerLifetimeScope();
|
||||
builder.RegisterGeneric(typeof(MongoBaseService<>)).As(typeof(IMongoBaseService<>)).InstancePerLifetimeScope();
|
||||
|
||||
builder.RegisterType<RedisService.RedisService>()
|
||||
.As<RedisService.IRedisService>()
|
||||
.InstancePerLifetimeScope();
|
||||
|
||||
builder.RegisterAssemblyTypes(typeof(ApiLogService).Assembly)
|
||||
.Where(t => t.Name.EndsWith("Service"))
|
||||
.AsImplementedInterfaces()
|
||||
.InstancePerLifetimeScope();
|
||||
builder.RegisterAssemblyTypes(typeof(FishingRoomService).Assembly)
|
||||
.Where(t => t.Name.EndsWith("Service"))
|
||||
.AsImplementedInterfaces()
|
||||
.InstancePerLifetimeScope();
|
||||
builder.RegisterAssemblyTypes(typeof(UserService.User.UserService).Assembly)
|
||||
.Where(t => t.Name.EndsWith("Service"))
|
||||
.AsImplementedInterfaces()
|
||||
.InstancePerLifetimeScope();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace FishRoomHost.Middleware
|
||||
{
|
||||
public class HubExceptionFilter : IHubFilter
|
||||
{
|
||||
private readonly ILogger<HubExceptionFilter> _logger;
|
||||
|
||||
public HubExceptionFilter(ILogger<HubExceptionFilter> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async ValueTask<object?> InvokeMethodAsync(
|
||||
HubInvocationContext invocationContext,
|
||||
Func<HubInvocationContext, ValueTask<object?>> next)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await next(invocationContext);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "Hub 调用异常: {Method}", invocationContext.HubMethodName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using Common.Utils;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace FishRoomHost.Middleware
|
||||
{
|
||||
public class MovementFilter : IHubFilter
|
||||
{
|
||||
public async ValueTask<object> InvokeMethodAsync(
|
||||
HubInvocationContext context,
|
||||
Func<HubInvocationContext, ValueTask<object>> next)
|
||||
{
|
||||
var arguments = context.HubMethodArguments;
|
||||
{
|
||||
|
||||
|
||||
//if (context.HubMethodName == "ChangeUserData" )
|
||||
//{
|
||||
// var obj = arguments[0].ToJson().ToObject<ChangeUserDataParam>();
|
||||
|
||||
// if (obj.Type == 8 || obj.Type == 6 || obj.Type == 7 || obj.Type == 4)
|
||||
// {
|
||||
// if (!RateLimiter.Allow(context.Context.ConnectionId))
|
||||
// {
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
return await next(context);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RateLimiter
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, RateData> _rates = new();
|
||||
|
||||
public static bool Allow(string connectionId)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var rate = _rates.GetOrAdd(connectionId, id => new RateData());
|
||||
|
||||
if (rate.Tokens < 30)
|
||||
{
|
||||
rate.Tokens++;
|
||||
rate.LastUpdate = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((now - rate.LastUpdate).TotalMilliseconds > 33)
|
||||
{
|
||||
rate.Tokens = 1;
|
||||
rate.LastUpdate = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private class RateData
|
||||
{
|
||||
public int Tokens { get; set; } = 30;
|
||||
public DateTime LastUpdate { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
using Autofac;
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Common;
|
||||
using Common.Request;
|
||||
using CommonService;
|
||||
|
||||
using FishRoomHost.Extension;
|
||||
using FishRoomHost.Middleware;
|
||||
using FishRoomService;
|
||||
using FishRoomService.Hubs;
|
||||
using FishRoomService.RoomService;
|
||||
using JWTHelper;
|
||||
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoRepository.Config;
|
||||
using NLog.Extensions.Logging;
|
||||
using NLog.Web;
|
||||
using RedisHelper;
|
||||
using SharpAbp.Infrastructure.Api.Middleware;
|
||||
using StackExchange.Redis;
|
||||
using System.Text.Json;
|
||||
using static Common.Utils.DateTimeTools;
|
||||
|
||||
Environment.SetEnvironmentVariable("SERVICE_NAME",
|
||||
Environment.GetEnvironmentVariable("SERVICE_NAME")
|
||||
?? System.Reflection.Assembly.GetEntryAssembly()?.GetName().Name
|
||||
?? "FishRoomHost");
|
||||
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}";
|
||||
}
|
||||
|
||||
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<FishRoomHub>, HubSend<FishRoomHub>>();
|
||||
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 redis
|
||||
|
||||
builder.Services.AddRedisCacheSingleton(builder.Configuration);
|
||||
|
||||
#endregion
|
||||
|
||||
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
|
||||
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
|
||||
{
|
||||
builder.RegisterModule<AutofacModule>();
|
||||
});
|
||||
|
||||
#region Cap
|
||||
|
||||
builder.Services.AddCap(builder.Configuration);
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
|
||||
}
|
||||
app.UseApiLogging();
|
||||
app.UseRouting();
|
||||
app.UseGlobalExceptionHandler();
|
||||
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseCors("Cors");
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapHub<FishRoomHub>("/fishingroomhub", 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));
|
||||
}
|
||||
});
|
||||
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
|
||||
try
|
||||
{
|
||||
var redis = scope.ServiceProvider.GetRequiredService<RedisService.IRedisService>();
|
||||
if (redis.GetGameRoomAllList()?.Any() != true)
|
||||
{
|
||||
var roomService = scope.ServiceProvider.GetRequiredService<IFishingRoomService>();
|
||||
await roomService.InitRoom();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "[Startup] 游戏房间初始化失败");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
app.Run();
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:6603",
|
||||
"sslPort": 44370
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:8004",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
name: webapi
|
||||
services:
|
||||
0524fishroom:
|
||||
image: 0524fishroom
|
||||
container_name: '0524fishroom'
|
||||
restart: always
|
||||
ports:
|
||||
- '5244:80'
|
||||
Reference in New Issue
Block a user