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