using System.Collections.Concurrent;
using System.Net.Sockets;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_Tasks.SocketServer;
namespace WIDESEAWCS_Tasks
{
///
/// 机械手客户端连接管理器 - 负责TCP客户端连接管理和事件订阅
///
public class RobotClientManager
{
private readonly TcpSocketServer _tcpSocket;
private readonly RobotStateManager _stateManager;
// 跟踪已经启动 HandleClientAsync 的客户端
private static readonly ConcurrentDictionary _handleClientStarted = new();
private static int _eventSubscribedFlag;
public event EventHandler? OnClientDisconnected;
public RobotClientManager(TcpSocketServer tcpSocket, RobotStateManager stateManager)
{
_tcpSocket = tcpSocket;
_stateManager = stateManager;
}
///
/// 确保客户端已连接并订阅消息事件
///
/// 设备IP地址
/// 机器人设备信息
/// 客户端是否可用(已连接且消息处理已启动)
public bool EnsureClientSubscribed(string ipAddress, RobotCraneDevice robotCrane)
{
// 检查是否有该客户端连接
var clientIds = _tcpSocket.GetClientIds();
bool isClientConnected = clientIds.Contains(ipAddress);
if (!isClientConnected)
{
// 客户端未连接,清理 HandleClientAsync 状态
_handleClientStarted.TryRemove(ipAddress, out _);
return false;
}
// 订阅一次 robot 事件(全局一次)- message事件由RobotJob订阅
if (System.Threading.Interlocked.CompareExchange(ref _eventSubscribedFlag, 1, 0) == 0)
{
_tcpSocket.RobotReceived += OnRobotReceived;
Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 机器人TCP断开事件已订阅");
}
// 获取TcpClient
TcpClient? tcpClient = null;
_tcpSocket._clients.TryGetValue(ipAddress, out tcpClient);
if (tcpClient == null)
{
// isClientConnected为true但无法获取tcpClient,列表可能不同步
_handleClientStarted.TryRemove(ipAddress, out _);
return false;
}
// 检查是否已经为这个客户端启动过 HandleClientAsync
bool alreadyStarted = _handleClientStarted.TryGetValue(ipAddress, out _);
if (!alreadyStarted)
{
Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 启动客户端消息处理: {ipAddress}");
// 重新获取最新的 state 对象
var latestStateForSubscribe = _stateManager.GetState(ipAddress);
if (latestStateForSubscribe != null)
{
// 标记为已启动
_handleClientStarted[ipAddress] = true;
_ = _tcpSocket.HandleClientAsync(tcpClient, robotCrane.IPAddress, _tcpSocket._cts.Token, latestStateForSubscribe)
.ContinueWith(t =>
{
if (t.IsFaulted)
{
Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] HandleClientAsync error: {t.Exception?.GetBaseException().Message}");
// 发生错误时,移除启动标志,允许下次重试
_handleClientStarted.TryRemove(ipAddress, out _);
}
}, TaskContinuationOptions.OnlyOnFaulted);
// 更新 IsEventSubscribed 状态
_stateManager.TryUpdateStateSafely(ipAddress, s =>
{
s.IsEventSubscribed = true;
return s;
});
}
}
return true;
}
///
/// 事件:客户端断开连接时触发
///
private Task OnRobotReceived(string clientId)
{
// 客户端断开连接,清理 HandleClientAsync 启动标志
_handleClientStarted.TryRemove(clientId, out _);
_stateManager.TryUpdateStateSafely(clientId, state =>
{
state.IsEventSubscribed = false;
state.CurrentAction = "";
state.OperStatus = "";
state.RobotArmObject = 0;
state.RobotControlMode = 0;
state.RobotRunMode = 0;
return state;
});
// 触发断开连接事件
OnClientDisconnected?.Invoke(this, _stateManager.GetState(clientId) ?? new RobotSocketState { IPAddress = clientId });
return Task.FromResult(null);
}
///
/// 检查客户端是否已连接
///
public bool IsClientConnected(string ipAddress)
{
var clientIds = _tcpSocket.GetClientIds();
return clientIds.Contains(ipAddress);
}
///
/// 发送消息到客户端
///
public async Task SendToClientAsync(string ipAddress, string message)
{
return await _tcpSocket.SendToClientAsync(ipAddress, message);
}
///
/// 获取TcpSocketServer引用(用于RobotJob直接访问)
///
public TcpSocketServer TcpSocket => _tcpSocket;
}
}