using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using WIDESEAWCS_S7Simulator.Core.Entities; using WIDESEAWCS_S7Simulator.Core.Enums; using WIDESEAWCS_S7Simulator.Core.Interfaces; using WIDESEAWCS_S7Simulator.Core.Persistence; using WIDESEAWCS_S7Simulator.Core.Server; namespace WIDESEAWCS_S7Simulator.Core.Manager { /// /// 仿真器实例管理器实现 /// 管理多个S7服务器实例的生命周期,提供线程安全的CRUD操作 /// public class SimulatorInstanceManager : ISimulatorInstanceManager { private readonly ConcurrentDictionary _instances = new(); private readonly IPersistenceService _persistenceService; private readonly ILogger _logger; private readonly ILoggerFactory _loggerFactory; /// public event EventHandler? InstanceStateChanged; /// /// 构造函数 /// /// 持久化服务 /// 日志记录器 /// 日志工厂 public SimulatorInstanceManager( IPersistenceService persistenceService, ILogger logger, ILoggerFactory loggerFactory) { _persistenceService = persistenceService ?? throw new ArgumentNullException(nameof(persistenceService)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); } /// public IReadOnlyList GetAllInstances() { return _instances.Values.ToList().AsReadOnly(); } /// public IS7ServerInstance? GetInstance(string instanceId) { if (string.IsNullOrWhiteSpace(instanceId)) { return null; } _instances.TryGetValue(instanceId, out var instance); return instance; } /// public bool InstanceExists(string instanceId) { return !string.IsNullOrWhiteSpace(instanceId) && _instances.ContainsKey(instanceId); } /// public async Task CreateInstanceAsync(InstanceConfig config) { if (config == null) { throw new ArgumentNullException(nameof(config)); } // 如果没有提供ID,生成新的GUID if (string.IsNullOrWhiteSpace(config.Id)) { config.Id = Guid.NewGuid().ToString("N"); _logger.LogDebug("为实例生成新ID: {InstanceId}", config.Id); } // 检查ID是否已存在 if (_instances.ContainsKey(config.Id)) { throw new InvalidOperationException($"实例ID {config.Id} 已存在"); } try { // 创建实例 var instanceLogger = _loggerFactory.CreateLogger(); var instance = new S7ServerInstance(config, instanceLogger); // 添加到字典 if (!_instances.TryAdd(config.Id, instance)) { throw new InvalidOperationException($"无法将实例 {config.Id} 添加到管理器"); } // 保存配置 await _persistenceService.SaveInstanceConfigAsync(config); // 触发状态变化事件 OnInstanceStateChanged(new InstanceStateChangedEventArgs { InstanceId = config.Id, OldStatus = InstanceStatus.Stopped, NewStatus = InstanceStatus.Stopped, InstanceState = instance.GetState() }); _logger.LogInformation("已创建实例 {InstanceId} ({InstanceName})", config.Id, config.Name); return instance; } catch (Exception ex) { _logger.LogError(ex, "创建实例 {InstanceId} 时发生错误", config.Id); throw; } } /// public async Task StartInstanceAsync(string instanceId) { if (string.IsNullOrWhiteSpace(instanceId)) { _logger.LogWarning("尝试启动实例时提供了空ID"); return false; } if (!_instances.TryGetValue(instanceId, out var instance)) { _logger.LogWarning("尝试启动不存在的实例 {InstanceId}", instanceId); return false; } try { var oldState = instance.GetState(); var oldStatus = oldState.Status; // 启动实例 var success = instance.Start(); if (success) { var newState = instance.GetState(); // 触发状态变化事件 OnInstanceStateChanged(new InstanceStateChangedEventArgs { InstanceId = instanceId, OldStatus = oldStatus, NewStatus = newState.Status, InstanceState = newState }); _logger.LogInformation("实例 {InstanceId} 已启动", instanceId); } else { _logger.LogWarning("实例 {InstanceId} 启动失败", instanceId); } return success; } catch (Exception ex) { _logger.LogError(ex, "启动实例 {InstanceId} 时发生异常", instanceId); return false; } } /// public async Task StopInstanceAsync(string instanceId) { if (string.IsNullOrWhiteSpace(instanceId)) { _logger.LogWarning("尝试停止实例时提供了空ID"); return; } if (!_instances.TryGetValue(instanceId, out var instance)) { _logger.LogWarning("尝试停止不存在的实例 {InstanceId}", instanceId); return; } try { var oldState = instance.GetState(); var oldStatus = oldState.Status; // 停止实例 instance.Stop(); // 同步内存数据到持久化存储 await _persistenceService.SaveMemoryDataAsync(instanceId, instance.MemoryStore); var newState = instance.GetState(); // 触发状态变化事件 OnInstanceStateChanged(new InstanceStateChangedEventArgs { InstanceId = instanceId, OldStatus = oldStatus, NewStatus = newState.Status, InstanceState = newState }); _logger.LogInformation("实例 {InstanceId} 已停止", instanceId); } catch (Exception ex) { _logger.LogError(ex, "停止实例 {InstanceId} 时发生异常", instanceId); } } /// public async Task RestartInstanceAsync(string instanceId) { if (string.IsNullOrWhiteSpace(instanceId)) { _logger.LogWarning("尝试重启实例时提供了空ID"); return false; } if (!_instances.TryGetValue(instanceId, out var instance)) { _logger.LogWarning("尝试重启不存在的实例 {InstanceId}", instanceId); return false; } try { var oldState = instance.GetState(); var oldStatus = oldState.Status; // 重启实例 var success = instance.Restart(); if (success) { var newState = instance.GetState(); // 触发状态变化事件 OnInstanceStateChanged(new InstanceStateChangedEventArgs { InstanceId = instanceId, OldStatus = oldStatus, NewStatus = newState.Status, InstanceState = newState }); _logger.LogInformation("实例 {InstanceId} 已重启", instanceId); } else { _logger.LogWarning("实例 {InstanceId} 重启失败", instanceId); } return success; } catch (Exception ex) { _logger.LogError(ex, "重启实例 {InstanceId} 时发生异常", instanceId); return false; } } /// public async Task DeleteInstanceAsync(string instanceId, bool deleteConfig = true) { if (string.IsNullOrWhiteSpace(instanceId)) { _logger.LogWarning("尝试删除实例时提供了空ID"); return; } if (!_instances.TryRemove(instanceId, out var instance)) { _logger.LogWarning("尝试删除不存在的实例 {InstanceId}", instanceId); return; } try { var oldState = instance.GetState(); // 停止实例 instance.Stop(); // 释放实例资源 instance.Dispose(); // 删除配置文件 if (deleteConfig) { await _persistenceService.DeleteInstanceConfigAsync(instanceId); } // 触发状态变化事件 OnInstanceStateChanged(new InstanceStateChangedEventArgs { InstanceId = instanceId, OldStatus = oldState.Status, NewStatus = InstanceStatus.Stopped, InstanceState = oldState }); _logger.LogInformation("实例 {InstanceId} 已删除", instanceId); } catch (Exception ex) { _logger.LogError(ex, "删除实例 {InstanceId} 时发生异常", instanceId); } } /// public InstanceState? GetInstanceState(string instanceId) { if (string.IsNullOrWhiteSpace(instanceId)) { return null; } if (!_instances.TryGetValue(instanceId, out var instance)) { return null; } return instance.GetState(); } /// public IReadOnlyList GetAllInstanceStates() { return _instances.Values .Select(i => i.GetState()) .ToList() .AsReadOnly(); } /// public async Task LoadSavedInstancesAsync(bool autoStart = true) { try { _logger.LogInformation("开始加载已保存的实例配置..."); // 加载所有配置 var configs = await _persistenceService.LoadAllInstanceConfigsAsync(); if (configs == null || configs.Count == 0) { _logger.LogInformation("没有找到已保存的实例配置"); return; } _logger.LogInformation("找到 {Count} 个已保存的实例配置", configs.Count); foreach (var config in configs) { try { // 创建实例 var instanceLogger = _loggerFactory.CreateLogger(); var instance = new S7ServerInstance(config, instanceLogger); // 添加到字典 if (_instances.TryAdd(config.Id, instance)) { // 加载内存数据 try { await _persistenceService.LoadMemoryDataAsync(config.Id, instance.MemoryStore); _logger.LogDebug("已加载实例 {InstanceId} 的内存数据", config.Id); } catch (Exception ex) { _logger.LogWarning(ex, "加载实例 {InstanceId} 的内存数据时发生警告", config.Id); } // 如果配置了自动启动,则启动实例 if (autoStart && config.AutoStart) { _logger.LogInformation("自动启动实例 {InstanceId} ({InstanceName})", config.Id, config.Name); var success = instance.Start(); if (success) { _logger.LogInformation("实例 {InstanceId} 自动启动成功", config.Id); } else { _logger.LogWarning("实例 {InstanceId} 自动启动失败", config.Id); } } // 触发状态变化事件 OnInstanceStateChanged(new InstanceStateChangedEventArgs { InstanceId = config.Id, OldStatus = InstanceStatus.Stopped, NewStatus = instance.State.Status, InstanceState = instance.GetState() }); _logger.LogInformation("已加载实例 {InstanceId} ({InstanceName})", config.Id, config.Name); } else { _logger.LogWarning("实例 {InstanceId} 已存在,跳过加载", config.Id); } } catch (Exception ex) { _logger.LogError(ex, "加载实例 {InstanceId} 时发生错误", config.Id); } } _logger.LogInformation("实例加载完成,共加载 {Count} 个实例", _instances.Count); } catch (Exception ex) { _logger.LogError(ex, "加载已保存的实例时发生异常"); } } /// public async Task StopAllInstancesAsync() { _logger.LogInformation("开始停止所有实例..."); var instanceIds = _instances.Keys.ToList(); foreach (var instanceId in instanceIds) { try { await StopInstanceAsync(instanceId); } catch (Exception ex) { _logger.LogError(ex, "停止实例 {InstanceId} 时发生异常", instanceId); } } _logger.LogInformation("所有实例已停止"); } /// public int GetRunningInstanceCount() { return _instances.Values.Count(i => i.State.Status == InstanceStatus.Running); } /// public int GetTotalInstanceCount() { return _instances.Count; } /// /// 触发实例状态变化事件 /// /// 事件参数 protected virtual void OnInstanceStateChanged(InstanceStateChangedEventArgs e) { InstanceStateChanged?.Invoke(this, e); } } }