|
|
@@ -14,6 +14,7 @@ using System.Security.Cryptography;
|
|
|
using System.Text;
|
|
|
using System.Threading;
|
|
|
using System.Threading.Tasks;
|
|
|
+using static System.Windows.Forms.AxHost;
|
|
|
|
|
|
namespace SWRIS.Core
|
|
|
{
|
|
|
@@ -45,6 +46,7 @@ namespace SWRIS.Core
|
|
|
private readonly ByteTransform byteTransform;
|
|
|
private const string PASSWORD = "WNDTM4";
|
|
|
private static ConcurrentDictionary<string, ClientState> _connectedClients;
|
|
|
+ private CancellationTokenSource ctsToken = new CancellationTokenSource();
|
|
|
public TcpServerFrame(string ipAddress, int port)
|
|
|
{
|
|
|
_ipAddress = ipAddress;
|
|
|
@@ -93,8 +95,24 @@ namespace SWRIS.Core
|
|
|
public void Stop()
|
|
|
{
|
|
|
_isRunning = false;
|
|
|
- _listener.Shutdown(SocketShutdown.Both);
|
|
|
- _listener?.Close();
|
|
|
+ // 取消心跳检测任务
|
|
|
+ ctsToken?.Cancel();
|
|
|
+ ctsToken?.Dispose();
|
|
|
+ ctsToken = null;
|
|
|
+ // 关闭所有客户端连接
|
|
|
+ foreach (var client in _connectedClients.Values)
|
|
|
+ {
|
|
|
+ SafeCloseClient(client);
|
|
|
+ }
|
|
|
+ _connectedClients.Clear();
|
|
|
+
|
|
|
+ // 关闭监听器
|
|
|
+ if (_listener != null && _listener.Connected)
|
|
|
+ {
|
|
|
+ _listener.Shutdown(SocketShutdown.Both);
|
|
|
+ _listener.Close();
|
|
|
+ _listener = null;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private void OnClientConnected(IAsyncResult ar)
|
|
|
@@ -126,23 +144,37 @@ namespace SWRIS.Core
|
|
|
}
|
|
|
private void StartHeartbeatCheck()
|
|
|
{
|
|
|
- ThreadPool.QueueUserWorkItem(act =>
|
|
|
+ ThreadPool.QueueUserWorkItem(async state =>
|
|
|
{
|
|
|
- while (_isRunning)
|
|
|
- {
|
|
|
- Thread.Sleep(TimeSpan.FromSeconds(5)); // 每5秒检测一次
|
|
|
+ var token = (CancellationTokenSource)state;
|
|
|
|
|
|
- foreach (var client in _connectedClients.ToArray())
|
|
|
+ while (_isRunning && !token.IsCancellationRequested)
|
|
|
+ {
|
|
|
+ try
|
|
|
{
|
|
|
- if ((DateTime.UtcNow - client.Value.LastActiveTime).TotalSeconds > 15)
|
|
|
+ await Task.Delay(TimeSpan.FromSeconds(5), token.Token);
|
|
|
+
|
|
|
+ foreach (var client in _connectedClients.ToArray())
|
|
|
{
|
|
|
- SafeCloseClient(client.Value);
|
|
|
- DebugMessageReceived?.Invoke(this,
|
|
|
- new DebugMessageReceivedEventArgs($"心跳超时,强制断开", ipAddress: client.Value.IpAddress));
|
|
|
+ if ((DateTime.UtcNow - client.Value.LastActiveTime).TotalSeconds > 15)
|
|
|
+ {
|
|
|
+ SafeCloseClient(client.Value);
|
|
|
+ DebugMessageReceived?.Invoke(this,
|
|
|
+ new DebugMessageReceivedEventArgs($"心跳超时,强制断开", ipAddress: client.Value.IpAddress));
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ catch (TaskCanceledException)
|
|
|
+ {
|
|
|
+ // 正常取消,退出循环
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.Error($"心跳检测异常: {ex.Message}", ex);
|
|
|
+ }
|
|
|
}
|
|
|
- });
|
|
|
+ }, ctsToken);
|
|
|
}
|
|
|
|
|
|
private async void OnDataReceived(IAsyncResult ar)
|