| | |
| | | using System.Collections.Concurrent; |
| | | using System.Linq; |
| | | using System.Net.NetworkInformation; |
| | | using HslCommunication; |
| | | using HslCommunication.Profinet.Siemens; |
| | | using HslCommunication.Reflection; |
| | |
| | | /// 客户端连接追踪 |
| | | /// </summary> |
| | | private readonly ConcurrentDictionary<string, S7ClientConnection> _clients = new(); |
| | | |
| | | /// <summary> |
| | | /// 连接监控定时器 |
| | | /// </summary> |
| | | private System.Threading.Timer? _connectionMonitorTimer; |
| | | |
| | | /// <summary> |
| | | /// 构造函数 |
| | |
| | | State.StartTime = DateTime.Now; |
| | | State.ErrorMessage = null; |
| | | |
| | | // 启动连接监控定时器(每5秒检查一次) |
| | | _connectionMonitorTimer = new System.Threading.Timer( |
| | | _ => MonitorConnections(), |
| | | null, |
| | | TimeSpan.FromSeconds(5), |
| | | TimeSpan.FromSeconds(5)); |
| | | |
| | | _logger.LogInformation("S7服务器实例 {InstanceId} 已成功启动,监听端口: {Port}", Config.Id, Config.Port); |
| | | return true; |
| | | } |
| | |
| | | |
| | | try |
| | | { |
| | | // 停止连接监控定时器 |
| | | _connectionMonitorTimer?.Dispose(); |
| | | _connectionMonitorTimer = null; |
| | | |
| | | if (_server != null) |
| | | { |
| | | // 停止前同步服务器数据到MemoryStore |
| | |
| | | State.ClientCount = _clients.Count; |
| | | State.Clients = _clients.Values.ToList(); |
| | | |
| | | // 返回状态副本 |
| | | // 返回状态副本,包含配置信息 |
| | | return new InstanceState |
| | | { |
| | | InstanceId = State.InstanceId, |
| | |
| | | StartTime = State.StartTime, |
| | | LastActivityTime = State.LastActivityTime, |
| | | Clients = new List<S7ClientConnection>(State.Clients), |
| | | ErrorMessage = State.ErrorMessage |
| | | }; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取完整状态(包含配置信息) |
| | | /// </summary> |
| | | public object GetFullState() |
| | | { |
| | | lock (_lock) |
| | | { |
| | | // 更新客户端连接数 |
| | | State.ClientCount = _clients.Count; |
| | | State.Clients = _clients.Values.ToList(); |
| | | |
| | | return new |
| | | { |
| | | InstanceId = State.InstanceId, |
| | | Name = Config.Name, |
| | | PLCType = Config.PLCType.ToString(), |
| | | Port = Config.Port, |
| | | Status = State.Status.ToString(), |
| | | ClientCount = State.ClientCount, |
| | | TotalRequests = State.TotalRequests, |
| | | StartTime = State.StartTime, |
| | | LastActivityTime = State.LastActivityTime, |
| | | Clients = State.Clients, |
| | | ErrorMessage = State.ErrorMessage |
| | | }; |
| | | } |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 监控客户端连接(通过检查TCP连接) |
| | | /// </summary> |
| | | private void MonitorConnections() |
| | | { |
| | | try |
| | | { |
| | | if (_server == null || State.Status != InstanceStatus.Running) |
| | | return; |
| | | |
| | | var currentConnections = new HashSet<string>(); |
| | | var now = DateTime.Now; |
| | | |
| | | // 获取当前所有TCP连接 |
| | | var tcpConnections = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections(); |
| | | |
| | | // 筛选出监听端口的已建立连接 |
| | | var connectionsOnPort = tcpConnections.Where(c => |
| | | c.LocalEndPoint.Port == Config.Port && |
| | | c.State == TcpState.Established); |
| | | |
| | | foreach (var connection in connectionsOnPort) |
| | | { |
| | | var endPoint = connection.RemoteEndPoint.ToString(); |
| | | currentConnections.Add(endPoint); |
| | | |
| | | // 检查是否是新连接 |
| | | if (!_clients.ContainsKey(endPoint)) |
| | | { |
| | | var clientConnection = new S7ClientConnection |
| | | { |
| | | ClientId = endPoint, |
| | | RemoteEndPoint = endPoint, |
| | | ConnectedTime = now, |
| | | LastActivityTime = now |
| | | }; |
| | | |
| | | _clients[endPoint] = clientConnection; |
| | | _logger.LogInformation("实例 {InstanceId} 检测到新客户端连接: {EndPoint}, 当前连接数: {Count}", |
| | | Config.Id, endPoint, _clients.Count); |
| | | } |
| | | else |
| | | { |
| | | // 更新活动时间 |
| | | _clients[endPoint].LastActivityTime = now; |
| | | } |
| | | } |
| | | |
| | | // 移除断开的连接 |
| | | var disconnectedClients = _clients.Keys.Where(k => !currentConnections.Contains(k)).ToList(); |
| | | foreach (var disconnected in disconnectedClients) |
| | | { |
| | | if (_clients.TryRemove(disconnected, out var client)) |
| | | { |
| | | _logger.LogInformation("实例 {InstanceId} 客户端断开: {EndPoint}, 当前连接数: {Count}", |
| | | Config.Id, disconnected, _clients.Count); |
| | | } |
| | | } |
| | | |
| | | // 更新状态 |
| | | State.ClientCount = _clients.Count; |
| | | State.LastActivityTime = now; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogWarning(ex, "监控客户端连接时发生错误"); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 增加请求计数并更新活动时间 |
| | | /// </summary> |
| | | private void IncrementRequestCount() |