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)}***"; } } }