using System; using Microsoft.Extensions.Logging; using YunDa.Server.ISMSTcp.Models; using YunDa.Server.ISMSTcp.Interfaces; namespace YunDa.Server.ISMSTcp.Services { /// /// 命令状态机实现 /// public class CommandStateMachine : ICommandStateMachine { private readonly ILogger _logger; private readonly object _lock = new object(); private CommandState _currentCommand; public CommandStateMachine(ILogger logger) { _logger = logger; } /// /// 当前命令状态 /// public CommandState CurrentCommand { get { lock (_lock) { return _currentCommand; } } } /// /// 是否有命令正在执行 /// public bool HasPendingCommand { get { lock (_lock) { return _currentCommand != null && _currentCommand.State == CommandExecutionState.WaitingForResponse; } } } /// /// 开始执行命令 /// /// 命令名称 /// 完整消息 /// 超时时间(秒) /// 是否成功开始执行 public bool StartCommand(string commandName, string fullMessage, int timeoutSeconds = 180) { if (string.IsNullOrWhiteSpace(commandName)) { _logger.LogWarning("Cannot start command with empty name"); return false; } lock (_lock) { // 检查是否有命令正在执行 if (_currentCommand != null && _currentCommand.State == CommandExecutionState.WaitingForResponse) { if (_currentCommand.IsTimeout) { _logger.LogWarning("Previous command '{PreviousCommand}' timed out, starting new command '{NewCommand}'", _currentCommand.CommandName, commandName); _currentCommand.State = CommandExecutionState.Timeout; } else { _logger.LogWarning("Command '{CurrentCommand}' is still pending (remaining: {RemainingTime:F1}s), cannot start new command '{NewCommand}'", _currentCommand.CommandName, _currentCommand.RemainingTimeoutSeconds, commandName); return false; } } // 创建新的命令状态 _currentCommand = new CommandState { CommandName = commandName, FullMessage = fullMessage, State = CommandExecutionState.WaitingForResponse, SentTime = DateTime.Now, TimeoutSeconds = timeoutSeconds }; _logger.LogInformation("Started command '{CommandName}' with timeout {TimeoutSeconds}s", commandName, timeoutSeconds); return true; } } /// /// 完成当前命令 /// /// 响应的命令名称(用于验证) /// 是否成功完成 public bool CompleteCommand(string commandName = null) { lock (_lock) { if (_currentCommand == null || _currentCommand.State != CommandExecutionState.WaitingForResponse) { _logger.LogWarning("No pending command to complete"); return false; } // 如果提供了命令名称,验证是否匹配 if (!string.IsNullOrEmpty(commandName) && !string.Equals(_currentCommand.CommandName, commandName, StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning("Command name mismatch: expected '{Expected}', got '{Actual}'", _currentCommand.CommandName, commandName); return false; } var executionTime = DateTime.Now.Subtract(_currentCommand.SentTime).TotalSeconds; _currentCommand.State = CommandExecutionState.Completed; _logger.LogInformation("Completed command '{CommandName}' in {ExecutionTime:F2}s", _currentCommand.CommandName, executionTime); return true; } } /// /// 设置命令超时 /// /// 是否有命令被设置为超时 public bool TimeoutCommand() { lock (_lock) { if (_currentCommand != null && _currentCommand.State == CommandExecutionState.WaitingForResponse) { _currentCommand.State = CommandExecutionState.Timeout; _logger.LogWarning("Command '{CommandName}' timed out after {TimeoutSeconds}s", _currentCommand.CommandName, _currentCommand.TimeoutSeconds); return true; } return false; } } /// /// 检查并处理超时 /// /// 是否有命令超时 public bool CheckAndHandleTimeout() { lock (_lock) { if (_currentCommand != null && _currentCommand.IsTimeout == true) { return TimeoutCommand(); } return false; } } /// /// 处理OK响应,解锁命令状态 /// /// 是否成功处理OK响应 public bool HandleOkResponse() { lock (_lock) { if (_currentCommand != null && _currentCommand.State == CommandExecutionState.WaitingForResponse) { var executionTime = DateTime.Now.Subtract(_currentCommand.SentTime).TotalSeconds; _currentCommand.State = CommandExecutionState.Completed; _logger.LogInformation("Command '{CommandName}' completed with OK response in {ExecutionTime:F2}s", _currentCommand.CommandName, executionTime); return true; } else if (_currentCommand != null) { _logger.LogWarning("Received OK response but command '{CommandName}' is in state: {State}", _currentCommand.CommandName, _currentCommand.State); } else { _logger.LogDebug("Received OK response but no command is currently pending"); } return false; } } /// /// 重置状态机 /// public void Reset() { lock (_lock) { if (_currentCommand != null) { _logger.LogInformation("Resetting command state machine, current command: '{CommandName}' in state: {State}", _currentCommand.CommandName, _currentCommand.State); } _currentCommand = null; } } } }