diff --git a/src/CloudGaming/Api/CloudGaming.ExtApi/Controllers/MonitorController.cs b/src/CloudGaming/Api/CloudGaming.ExtApi/Controllers/MonitorController.cs
new file mode 100644
index 0000000..790d167
--- /dev/null
+++ b/src/CloudGaming/Api/CloudGaming.ExtApi/Controllers/MonitorController.cs
@@ -0,0 +1,11 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace CloudGaming.ExtApi.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class MonitorController : ControllerBase
+ {
+ }
+}
diff --git a/src/CloudGaming/Api/CloudGaming.ExtApi/Program.cs b/src/CloudGaming/Api/CloudGaming.ExtApi/Program.cs
index f378234..e0815de 100644
--- a/src/CloudGaming/Api/CloudGaming.ExtApi/Program.cs
+++ b/src/CloudGaming/Api/CloudGaming.ExtApi/Program.cs
@@ -2,6 +2,7 @@ using CloudGaming.Code.AppExtend;
using CloudGaming.Code.DataAccess.MultiTenantUtil;
using CloudGaming.Code.Filter;
using CloudGaming.Code.Game;
+using CloudGaming.Code.Monitor;
using HuanMeng.DotNetCore.MiddlewareExtend;
using HuanMeng.DotNetCore.SwaggerUtile;
@@ -86,6 +87,7 @@ builder.Services.AddSwaggerGen(c =>
builder.AddAppConfigClient();
//添加游戏服务
builder.AddPlayGameServer();
+builder.AddMonitorConfig();
var app = builder.Build();
// Configure the HTTP request pipeline.
@@ -108,7 +110,7 @@ app.UseSwaggerUI(c =>
app.UseAuthorization();
//数据库中间件
-app.UseMultiTenant();
+app.UseMultiTenantExt();
app.MapControllers();
app.UseMiddlewareAll();
#region 默认请求
diff --git a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs
index 38a8847..aae4b50 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/AppConfigurationExtend.cs
@@ -53,6 +53,25 @@ namespace CloudGaming.Code.AppExtend
return AppConfigs.FirstOrDefault().Value;
}
///
+ /// 获取配置项
+ ///
+ ///
+ ///
+ public static AppConfig GetAppConfig(Guid tenantId)
+ {
+ var appConfig = AppConfigs.Where(it => it.Value.TenantId == tenantId).Select(it => it.Value).FirstOrDefault();
+ if (appConfig != null)
+ {
+ return appConfig;
+ }
+ if (AppConfigs.TryGetValue("default", out appConfig))
+ {
+ return appConfig;
+ }
+
+ return AppConfigs.FirstOrDefault().Value;
+ }
+ ///
///
///
///
diff --git a/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj b/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj
index cc5eb55..e6cba50 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj
+++ b/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj
@@ -19,6 +19,9 @@
+
+
+
diff --git a/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantExtMiddleware.cs b/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantExtMiddleware.cs
new file mode 100644
index 0000000..58b11f5
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantExtMiddleware.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.Code.DataAccess.MultiTenantUtil;
+
+///
+/// 多租户中间件
+///
+public class MultiTenantExtMiddleware
+{
+ private readonly RequestDelegate _next;
+ public MultiTenantExtMiddleware(RequestDelegate next)
+ {
+ _next = next;
+ }
+
+
+ ///
+ /// 根据HttpContext获取并设置当前租户ID
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task Invoke(HttpContext context,
+ IServiceProvider _serviceProvider,
+ AppConfig appConfig)
+ {
+ AppConfig app = null;
+ if (context.Request.Headers.TryGetValue("tenantId", out var str))
+ {
+ if (Guid.TryParse(str, out Guid tenantId))
+ {
+ app = AppConfigurationExtend.GetAppConfig(tenantId);
+ }
+ }
+ if (app == null)
+ {
+ var host = context.Request.Host.Host;
+ app = AppConfigurationExtend.GetAppConfig(host);
+ }
+ if (string.IsNullOrEmpty(appConfig.Identifier))
+ {
+ app.ToAppConfig(appConfig);
+ }
+ await _next.Invoke(context);
+ }
+}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantExtension.cs b/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantExtension.cs
index fa5831a..3bda5d1 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantExtension.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantExtension.cs
@@ -58,6 +58,16 @@ namespace CloudGaming.Code.DataAccess.MultiTenantUtil
{
return app.UseMiddleware();
}
+ ///
+ /// 多租户IApplicationBuilder扩展
+ ///
+ ///
+ ///
+ public static IApplicationBuilder UseMultiTenantExt(this IApplicationBuilder app)
+ {
+ return app.UseMiddleware();
+ }
+
}
}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantTenantMiddleware.cs b/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantTenantMiddleware.cs
index 0785ef5..55a7218 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantTenantMiddleware.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/DataAccess/MultiTenantUtil/MultiTenantTenantMiddleware.cs
@@ -7,39 +7,38 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace CloudGaming.Code.DataAccess.MultiTenantUtil
+namespace CloudGaming.Code.DataAccess.MultiTenantUtil;
+
+///
+/// 多租户中间件
+///
+public class MultiTenantTenantMiddleware
{
- ///
- /// 多租户中间件
- ///
- public class MultiTenantTenantMiddleware
+ private readonly RequestDelegate _next;
+ public MultiTenantTenantMiddleware(RequestDelegate next)
{
- private readonly RequestDelegate _next;
- public MultiTenantTenantMiddleware(RequestDelegate next)
+ _next = next;
+ }
+
+
+ ///
+ /// 根据HttpContext获取并设置当前租户ID
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task Invoke(HttpContext context,
+ IServiceProvider _serviceProvider,
+ AppConfig appConfig)
+ {
+
+ var host = context.Request.Host.Host;
+ var app = AppConfigurationExtend.GetAppConfig(host);
+ if (string.IsNullOrEmpty(appConfig.Identifier))
{
- _next = next;
- }
-
-
- ///
- /// 根据HttpContext获取并设置当前租户ID
- ///
- ///
- ///
- ///
- ///
- public virtual async Task Invoke(HttpContext context,
- IServiceProvider _serviceProvider,
- AppConfig appConfig)
- {
-
- var host = context.Request.Host.Host;
- var app = AppConfigurationExtend.GetAppConfig(host);
- if (string.IsNullOrEmpty(appConfig.Identifier))
- {
- app.ToAppConfig(appConfig);
- }
- await _next.Invoke(context);
+ app.ToAppConfig(appConfig);
}
+ await _next.Invoke(context);
}
}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Game/PlayGameProcessor.cs b/src/CloudGaming/Code/CloudGaming.Code/Game/PlayGameProcessor.cs
index 0e18b06..9cca940 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/Game/PlayGameProcessor.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/Game/PlayGameProcessor.cs
@@ -1,6 +1,7 @@
using CloudGaming.Code.Contract;
using CloudGaming.Code.DataAccess;
using CloudGaming.Code.JY;
+using CloudGaming.Code.Monitor;
using CloudGaming.DtoModel.PlayGame;
using HuanMeng.DotNetCore.Processors;
@@ -125,8 +126,16 @@ public class PlayGameProcessor(IServiceProvider serviceProvider) : ThreadProcess
user.PlayGameUserNotQueue();
await user.SaveChangesAsync(dao, redis).ConfigureAwait(false);
}
+ if (!MonitorExtend.AppMonitorConfigs.TryGetValue(app.Identifier, out var appMonitorInfo))
+ {
+ appMonitorInfo = new DtoModel.Other.AppMonitorInfo() { };
+ MonitorExtend.AppMonitorConfigs.TryAdd(app.Identifier, appMonitorInfo);
+ }
+ //替换引用
+ appMonitorInfo.PlayGameUserInfos = gameInfoList;
+
//状态统计
- var gameStatusStatistics = gameInfoList.GroupBy(it => it.GameStatus).ToDictionary(it => it.Key, it => it.Count());// .Select(it => new { GameStatus = it.Key, GameCount = it.Count() }).ToList();
+ //var gameStatusStatistics = gameInfoList.GroupBy(it => it.GameStatus).ToDictionary(it => it.Key, it => it.Count());// .Select(it => new { GameStatus = it.Key, GameCount = it.Count() }).ToList();
}
///
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Monitor/MonitorExtend.cs b/src/CloudGaming/Code/CloudGaming.Code/Monitor/MonitorExtend.cs
new file mode 100644
index 0000000..29bff36
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/Monitor/MonitorExtend.cs
@@ -0,0 +1,50 @@
+using AgileConfig.Client;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using CloudGaming.Code.DataAccess.MultiTenantUtil;
+using CloudGaming.DtoModel.Other;
+
+using Quartz;
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.Code.Monitor;
+
+///
+/// 监控扩展类
+///
+public static class MonitorExtend
+{
+ ///
+ ///
+ ///
+ public static ConcurrentDictionary AppMonitorConfigs { get; set; } = new ConcurrentDictionary();
+
+
+ public static WebApplicationBuilder AddMonitorConfig(this WebApplicationBuilder builder)
+ {
+ // 添加 Quartz 配置
+ builder.Services.AddQuartz(q =>
+ {
+ // 注册作业和触发器
+ var jobKey = new JobKey("MonitorProcessor");
+ q.AddJob(opts => opts.WithIdentity(jobKey));
+
+ q.AddTrigger(opts => opts
+ .ForJob(jobKey)
+ .WithIdentity("monitorTrigger")
+ .StartNow()
+ .WithSimpleSchedule(x => x.WithIntervalInSeconds(5).RepeatForever()));
+ });
+
+ // 添加 Quartz 托管服务
+ builder.Services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
+
+ return builder;
+ }
+}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Monitor/MonitorProcessor.cs b/src/CloudGaming/Code/CloudGaming.Code/Monitor/MonitorProcessor.cs
new file mode 100644
index 0000000..53a08fc
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/Monitor/MonitorProcessor.cs
@@ -0,0 +1,28 @@
+using Quartz;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.Code.Monitor;
+
+
+///
+///
+///
+public class MonitorProcessor : IJob
+{
+ public MonitorProcessor(IServiceProvider serviceProvider)
+ {
+
+ }
+
+ public Task Execute(IJobExecutionContext context)
+ {
+ Console.WriteLine($"MessageService:");
+ //throw new NotImplementedException();
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Other/MonitorBLL.cs b/src/CloudGaming/Code/CloudGaming.Code/Other/MonitorBLL.cs
new file mode 100644
index 0000000..1582713
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/Other/MonitorBLL.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.Code.Other
+{
+ ///
+ /// 监控类
+ ///
+ public class MonitorBLL : CloudGamingBase
+ {
+ public MonitorBLL(IServiceProvider serviceProvider) : base(serviceProvider)
+ {
+ }
+ }
+}
diff --git a/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoCache.cs b/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoCache.cs
index 24aa972..f1cda08 100644
--- a/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoCache.cs
+++ b/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoCache.cs
@@ -12,7 +12,7 @@ namespace CloudGaming.DtoModel.Account.User
///
/// 用户缓存
///
- public class UserInfoCache : UserInfo
+ public class UserInfoCache : UserInfo
{
///
/// 最后一次实名认证时间
diff --git a/src/CloudGaming/Model/CloudGaming.DtoModel/Other/AppMonitorInfo.cs b/src/CloudGaming/Model/CloudGaming.DtoModel/Other/AppMonitorInfo.cs
new file mode 100644
index 0000000..a1fd2f3
--- /dev/null
+++ b/src/CloudGaming/Model/CloudGaming.DtoModel/Other/AppMonitorInfo.cs
@@ -0,0 +1,72 @@
+using CloudGaming.DtoModel.Account.User;
+using CloudGaming.DtoModel.PlayGame;
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.DtoModel.Other;
+
+///
+/// app监控数据
+///
+public class AppMonitorInfo
+{
+ ///
+ /// 用户所有的游戏状态
+ ///
+ public List PlayGameUserInfos { get; set; }
+
+ ///
+ /// 在线人数
+ ///
+ public List OnlineUser { get; set; }
+
+ ///
+ /// 用户游戏状态统计
+ ///
+ public Dictionary PlayGameStatusStatistics() => PlayGameUserInfos.GroupBy(it => it.GameStatus).ToDictionary(it => it.Key, it => it.Count());
+
+ ///
+ /// 今日注册人数
+ ///
+ public int TodayRegisteredUsers { get; set; }
+
+ ///
+ /// 今日登录人数
+ ///
+ public int TodayLoggedInUsers { get; set; }
+
+ ///
+ /// 当前在线人数
+ ///
+ public int CurrentOnlineUsers { get; set; }
+
+ ///
+ /// 当前玩游戏人数
+ ///
+ public int CurrentPlayingUsers { get; set; }
+
+ ///
+ /// 当前排队人数
+ ///
+ public int CurrentQueuedUsers { get; set; }
+
+ ///
+ /// 今日意向订单
+ ///
+ public int TodayIntendedOrders { get; set; }
+
+ ///
+ /// 今日支付订单
+ ///
+ public int TodayPaidOrders { get; set; }
+
+ ///
+ /// 今日充值金额
+ ///
+ public decimal TodayRechargeAmount { get; set; }
+}