using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using YunDa.Server.ISMSTcp.Configuration; using YunDa.Server.ISMSTcp.Interfaces; namespace YunDa.Server.ISMSTcp.Services { /// /// 自动连接服务 - 负责程序启动时自动连接TCP服务端 /// public class AutoConnectionService : BackgroundService { private readonly ILogger _logger; private readonly ITcpClient _tcpClient; private readonly ISMSServerConfiguration _config; private Timer? _connectionCheckTimer; public AutoConnectionService( ILogger logger, ITcpClient tcpClient, IOptions config) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _tcpClient = tcpClient ?? throw new ArgumentNullException(nameof(tcpClient)); _config = config?.Value ?? throw new ArgumentNullException(nameof(config)); } /// /// 执行自动连接服务 /// /// 停止令牌 /// 执行任务 protected override async Task ExecuteAsync(CancellationToken stoppingToken) { try { if (!_config.EnableAutoConnect) { _logger.LogInformation("Auto connection is disabled in configuration"); return; } // 等待指定的延迟时间,让其他服务完全启动 _logger.LogInformation("Auto connection service starting in {Delay} seconds...", _config.AutoConnectDelaySeconds); await Task.Delay(TimeSpan.FromSeconds(_config.AutoConnectDelaySeconds), stoppingToken); // 尝试初始连接 await AttemptInitialConnectionAsync(stoppingToken); // 启动定期连接检查 StartConnectionHealthCheck(stoppingToken); // 保持服务运行 while (!stoppingToken.IsCancellationRequested) { await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); } } catch (OperationCanceledException) { _logger.LogInformation("Auto connection service was cancelled"); } catch (Exception ex) { _logger.LogError(ex, "Auto connection service encountered an error"); } finally { _connectionCheckTimer?.Dispose(); } } /// /// 尝试初始连接 /// /// 取消令牌 /// 连接任务 private async Task AttemptInitialConnectionAsync(CancellationToken cancellationToken) { try { _logger.LogInformation("Attempting initial connection to {IP}:{Port}", _config.ServerIP, _config.ServerPort); await _tcpClient.ConnectAsync(_config.ServerIP, _config.ServerPort, cancellationToken); if (_tcpClient.IsConnected) { _logger.LogInformation("Initial connection successful"); } else { _logger.LogWarning("Initial connection failed, but reconnection mechanism should handle this"); } } catch (Exception ex) { _logger.LogError(ex, "Error during initial connection attempt"); } } /// /// 启动连接健康检查 /// /// 取消令牌 private void StartConnectionHealthCheck(CancellationToken cancellationToken) { if (!_config.EnableConnectionRetry) { _logger.LogInformation("Connection health check is disabled"); return; } _logger.LogInformation("Starting connection health check with interval of 60 seconds"); _connectionCheckTimer = new Timer(async _ => { if (cancellationToken.IsCancellationRequested) return; try { await _tcpClient.EnsureConnectedAsync(cancellationToken); } catch (Exception ex) { _logger.LogError(ex, "Error during connection health check"); } }, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); } /// /// 停止服务时的清理工作 /// /// 取消令牌 /// 停止任务 public override async Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation("Auto connection service is stopping..."); _connectionCheckTimer?.Dispose(); _connectionCheckTimer = null; await base.StopAsync(cancellationToken); _logger.LogInformation("Auto connection service stopped"); } /// /// 释放资源 /// public override void Dispose() { _connectionCheckTimer?.Dispose(); base.Dispose(); } } }