using System; using System.Diagnostics; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using Aging.Infrastructure.Contracts; using ConnectionUtil; using log4net; namespace Aging.Infrastructure.Drivers { /// /// TCP 原始通信驱动适配器。 /// 封装 ConnectionUtil.TcpClientWrapper,实现统一的 IDeviceDriver 接口。 /// public sealed class TcpRawDriverAdapter : IDeviceDriver { private static readonly ILog Log = LogManager.GetLogger(typeof(TcpRawDriverAdapter)); private readonly string _ip; private readonly int _port; private TcpClientWrapper? _client; private bool _disposed; private readonly Stopwatch _latencyStopwatch = new Stopwatch(); private double _lastLatencyMs; private string _lastError = string.Empty; private DateTime? _lastErrorTime; private int _reconnectCount; /// public string DeviceId { get; } /// public bool IsConnected => _client?.IsConnected ?? false; /// public event EventHandler? ConnectionChanged; /// /// 初始化 TCP 原始通信驱动适配器 /// /// 设备唯一标识符 /// 目标 IP 地址 /// 目标端口号 public TcpRawDriverAdapter(string deviceId, string ip, int port) { DeviceId = deviceId ?? throw new ArgumentNullException(nameof(deviceId)); _ip = ip ?? throw new ArgumentNullException(nameof(ip)); _port = port; } /// public async Task ConnectAsync(CancellationToken ct) { ThrowIfDisposed(); Log.Info($"[TCP] 设备 {DeviceId} 正在连接 {_ip}:{_port}..."); try { _client = new TcpClientWrapper(_ip, _port); bool success = await _client.ConnectAsync(); if (!success) { _lastError = "连接失败"; _lastErrorTime = DateTime.Now; throw new InvalidOperationException($"[TCP] 设备 {DeviceId} 连接 {_ip}:{_port} 失败"); } _lastError = string.Empty; Log.Info($"[TCP] 设备 {DeviceId} 已成功连接到 {_ip}:{_port}"); OnConnectionChanged(true, "连接成功"); } catch (Exception ex) { _lastError = ex.Message; _lastErrorTime = DateTime.Now; Log.Error($"[TCP] 设备 {DeviceId} 连接异常: {ex.Message}", ex); throw; } } /// public Task DisconnectAsync() { ThrowIfDisposed(); Log.Info($"[TCP] 设备 {DeviceId} 正在断开连接..."); try { if (_client != null) { _client?.Close(); _client = null; } Log.Info($"[TCP] 设备 {DeviceId} 已断开连接"); OnConnectionChanged(false, "主动断开"); } catch (Exception ex) { _lastError = ex.Message; _lastErrorTime = DateTime.Now; Log.Error($"[TCP] 设备 {DeviceId} 断开连接异常: {ex.Message}", ex); } return Task.CompletedTask; } /// public async Task SendCommandAsync(string command, CancellationToken ct) { ThrowIfDisposed(); if (!IsConnected) throw new InvalidOperationException("[TCP] 设备未连接"); _latencyStopwatch.Restart(); try { Log.Debug($"[TCP] 设备 {DeviceId} 发送命令: {command}"); string response = await _client.SendMessageAsync(command); _latencyStopwatch.Stop(); _lastLatencyMs = _latencyStopwatch.Elapsed.TotalMilliseconds; Log.Debug($"[TCP] 设备 {DeviceId} 收到响应: {response} (延迟 {_lastLatencyMs:F2}ms)"); return response; } catch (Exception ex) { _latencyStopwatch.Stop(); _lastLatencyMs = _latencyStopwatch.Elapsed.TotalMilliseconds; _lastError = ex.Message; _lastErrorTime = DateTime.Now; Log.Error($"[TCP] 设备 {DeviceId} 发送命令失败: {ex.Message}", ex); throw; } } /// public async Task QueryAsync(string query, CancellationToken ct) { ThrowIfDisposed(); if (!IsConnected) throw new InvalidOperationException("[TCP] 设备未连接"); _latencyStopwatch.Restart(); try { Log.Debug($"[TCP] 设备 {DeviceId} 发送查询: {query}"); // 使用较短超时进行查询操作 string response = await _client.SendMessageAsync(query, TimeSpan.FromSeconds(5)); _latencyStopwatch.Stop(); _lastLatencyMs = _latencyStopwatch.Elapsed.TotalMilliseconds; Log.Debug($"[TCP] 设备 {DeviceId} 查询响应: {response} (延迟 {_lastLatencyMs:F2}ms)"); return response; } catch (Exception ex) { _latencyStopwatch.Stop(); _lastLatencyMs = _latencyStopwatch.Elapsed.TotalMilliseconds; _lastError = ex.Message; _lastErrorTime = DateTime.Now; Log.Error($"[TCP] 设备 {DeviceId} 查询失败: {ex.Message}", ex); throw; } } /// public DeviceDriverStatus GetStatus() { return new DeviceDriverStatus { IsConnected = IsConnected, IsHealthy = IsConnected && string.IsNullOrEmpty(_lastError), LastError = _lastError, LastErrorTime = _lastErrorTime, LatencyMs = _lastLatencyMs, ReconnectCount = _reconnectCount }; } /// public void Dispose() { if (_disposed) return; _disposed = true; try { _client?.Dispose(); } catch (Exception ex) { Log.Error($"[TCP] 设备 {DeviceId} 释放资源异常: {ex.Message}", ex); } } /// /// 触发连接状态变化事件 /// private void OnConnectionChanged(bool isConnected, string reason) { ConnectionChanged?.Invoke(this, new DeviceConnectionEventArgs { DeviceId = DeviceId, IsConnected = isConnected, Reason = reason }); if (!isConnected) { _reconnectCount++; } } /// /// 检查是否已释放 /// private void ThrowIfDisposed() { if (_disposed) throw new ObjectDisposedException(nameof(TcpRawDriverAdapter)); } } }