using LiveForum.IService.Others;
using LiveForum.Model.Dto.Others;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SKIT.FlurlHttpClient.Wechat.Api;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace LiveForum.Service.Others
{
///
/// 微信 API 客户端管理器实现(支持配置热更新)
///
public class WechatApiClientManager : IWechatApiClientManager
{
private readonly IOptionsMonitor _configMonitor;
private readonly ILogger _logger;
private readonly object _lockObject = new object();
private WechatApiClient _client;
private string _currentAppId;
public WechatApiClientManager(
IOptionsMonitor configMonitor,
ILogger logger)
{
_configMonitor = configMonitor;
_logger = logger;
// 监听配置变更
_configMonitor.OnChange(OnConfigChanged);
// 初始化客户端
InitializeClient();
}
///
/// 初始化客户端
///
private void InitializeClient()
{
try
{
var config = _configMonitor.CurrentValue;
// 验证配置
if (!ValidateConfig(config))
{
_logger.LogWarning("微信配置验证失败,无法创建客户端");
_client = null;
_currentAppId = null;
return;
}
var options = new WechatApiClientOptions()
{
AppId = config.AppId,
AppSecret = config.AppSecret
};
lock (_lockObject)
{
_client = new WechatApiClient(options);
_currentAppId = config.AppId;
}
var appIdDisplay = GetMaskedAppId(config.AppId);
_logger.LogInformation("微信 API 客户端已初始化 - AppId: {AppId}", appIdDisplay);
}
catch (Exception ex)
{
_logger.LogError(ex, "初始化微信 API 客户端失败");
_client = null;
_currentAppId = null;
}
}
///
/// 验证配置
///
private bool ValidateConfig(WechatConfig config)
{
if (config == null)
{
_logger.LogError("微信配置为空");
return false;
}
if (string.IsNullOrWhiteSpace(config.AppId))
{
_logger.LogError("微信 AppId 为空");
return false;
}
if (string.IsNullOrWhiteSpace(config.AppSecret))
{
_logger.LogError("微信 AppSecret 为空");
return false;
}
return true;
}
///
/// 获取微信 API 客户端实例
///
public WechatApiClient GetClient()
{
lock (_lockObject)
{
if (_client == null)
{
_logger.LogWarning("微信 API 客户端不可用,尝试重新初始化");
InitializeClient();
}
return _client;
}
}
///
/// 重新加载客户端(配置变更时调用)
///
public bool Reload()
{
try
{
_logger.LogInformation("开始重新加载微信 API 客户端...");
var newConfig = _configMonitor.CurrentValue;
// 验证新配置
if (!ValidateConfig(newConfig))
{
_logger.LogWarning("新配置验证失败,无法重新加载客户端");
return false;
}
WechatApiClient oldClient = null;
lock (_lockObject)
{
// 保存旧客户端引用(用于延迟 Dispose)
oldClient = _client;
// 创建新客户端
var options = new WechatApiClientOptions()
{
AppId = newConfig.AppId,
AppSecret = newConfig.AppSecret
};
_client = new WechatApiClient(options);
_currentAppId = newConfig.AppId;
var appIdDisplay = GetMaskedAppId(newConfig.AppId);
_logger.LogInformation("微信 API 客户端已重新加载 - 新 AppId: {AppId}", appIdDisplay);
}
// 延迟释放旧客户端(确保正在进行的请求完成)
//ScheduleDispose(oldClient);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "重新加载微信 API 客户端失败");
return false;
}
}
///
/// 检查客户端是否可用
///
public bool IsAvailable()
{
lock (_lockObject)
{
return _client != null;
}
}
///
/// 获取当前配置的 AppId
///
public string GetCurrentAppId()
{
lock (_lockObject)
{
return _currentAppId;
}
}
///
/// 配置变更回调
///
private void OnConfigChanged(WechatConfig newConfig)
{
var newAppIdDisplay = GetMaskedAppId(newConfig?.AppId);
_logger.LogInformation("检测到微信配置变更 - 新 AppId: {AppId}", newAppIdDisplay);
// 自动重新加载(可选,也可以手动调用)
// Reload();
}
///
/// 延迟释放旧客户端
///
private void ScheduleDispose(WechatApiClient oldClient)
{
if (oldClient == null) return;
// 延迟30秒后释放,确保所有正在进行的请求完成
Task.Run(async () =>
{
try
{
await Task.Delay(TimeSpan.FromSeconds(30));
// 检查是否实现了 IDisposable
if (oldClient is IDisposable disposable)
{
disposable.Dispose();
_logger.LogInformation("旧的微信 API 客户端已释放");
}
}
catch (Exception ex)
{
_logger.LogError(ex, "释放旧的微信 API 客户端时发生错误");
}
});
}
///
/// 获取脱敏的 AppId(用于日志)
///
private string GetMaskedAppId(string appId)
{
if (string.IsNullOrEmpty(appId))
return "未配置";
if (appId.Length <= 8)
return appId;
return $"{appId.Substring(0, 8)}***";
}
}
}