From 9d1660270272180cd71147d6ddd53d1382643d2e Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 02 十一月 2026 18:00:14 +0800
Subject: [PATCH] merge: 并入远程 Initial commit 作为历史根节点
---
ConnectionUtil/TcpClient.cs | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 254 insertions(+), 0 deletions(-)
diff --git a/ConnectionUtil/TcpClient.cs b/ConnectionUtil/TcpClient.cs
new file mode 100644
index 0000000..33d6f72
--- /dev/null
+++ b/ConnectionUtil/TcpClient.cs
@@ -0,0 +1,254 @@
+锘縰sing System;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ConnectionUtil
+{
+ /// <summary>
+ /// TCP瀹㈡埛绔寘瑁呯被
+ /// </summary>
+ /// <summary>
+ /// TCP瀹㈡埛绔寘瑁呯被
+ /// </summary>
+ public class TcpClientWrapper : IDisposable
+ {
+ private System.Net.Sockets.TcpClient _client;
+ private NetworkStream _stream;
+ private readonly string _host;
+ private readonly int _port;
+ private bool _isConnected;
+ private readonly CancellationTokenSource _cts;
+ private Task _heartbeatTask;
+ private readonly SemaphoreSlim _sendReceiveLock;
+
+ /// <summary>
+ /// 鍒濆鍖朤CP瀹㈡埛绔�
+ /// </summary>
+ /// <param name="host">鏈嶅姟鍣ㄥ湴鍧�</param>
+ /// <param name="port">鏈嶅姟鍣ㄧ鍙�</param>
+ public TcpClientWrapper(string host = "127.0.0.1", int port = 6543)
+ {
+ _host = host;
+ _port = port;
+ _cts = new CancellationTokenSource();
+ _sendReceiveLock = new SemaphoreSlim(1, 1);
+ }
+
+ /// <summary>
+ /// 寮傛杩炴帴鍒版湇鍔″櫒
+ /// </summary>
+ /// <returns>杩炴帴鏄惁鎴愬姛</returns>
+ public async Task<bool> ConnectAsync()
+ {
+ try
+ {
+ _client = new System.Net.Sockets.TcpClient();
+ await _client.ConnectAsync(_host, _port);
+ _stream = _client.GetStream();
+ _isConnected = true;
+
+ // 鍚姩蹇冭烦浠诲姟
+ _heartbeatTask = StartHeartbeatAsync(_cts.Token);
+
+ Console.WriteLine($"鎴愬姛杩炴帴鍒版湇鍔″櫒 {_host}:{_port}");
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"杩炴帴鏈嶅姟鍣ㄥけ璐ワ細{ex.Message}");
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// 鍚屾杩炴帴鍒版湇鍔″櫒
+ /// </summary>
+ /// <returns>杩炴帴鏄惁鎴愬姛</returns>
+ public bool Connect()
+ {
+ try
+ {
+ _client = new System.Net.Sockets.TcpClient();
+ _client.Connect(_host, _port);
+ _stream = _client.GetStream();
+ _isConnected = true;
+
+ // 鍚姩蹇冭烦浠诲姟
+ _heartbeatTask = StartHeartbeatAsync(_cts.Token);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"杩炴帴鏈嶅姟鍣ㄥけ璐ワ細{ex.Message}");
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// 鍚姩蹇冭烦妫�娴�
+ /// </summary>
+ private async Task StartHeartbeatAsync(CancellationToken token)
+ {
+ while (!token.IsCancellationRequested && _isConnected)
+ {
+ try
+ {
+ await Task.Delay(20000, token); // 20绉掑彂閫佷竴娆″績璺�
+ if (_isConnected)
+ {
+ await SendMessageAsync("ping");
+ }
+ }
+ catch (OperationCanceledException)
+ {
+ break;
+ }
+ catch (Exception)
+ {
+ _isConnected = false;
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// 鍙戦�佹秷鎭苟鎺ユ敹鍝嶅簲
+ /// </summary>
+ /// <typeparam name="T">鍝嶅簲鏁版嵁绫诲瀷</typeparam>
+ /// <param name="data">瑕佸彂閫佺殑鏁版嵁瀵硅薄</param>
+ /// <param name="timeout">瓒呮椂鏃堕棿</param>
+ /// <returns>鏈嶅姟鍣ㄥ搷搴旀暟鎹�</returns>
+ public async Task<string> SendMessageAsync(string message, TimeSpan? timeout = null)
+ {
+ if (!_isConnected)
+ {
+ throw new InvalidOperationException("鏈繛鎺ュ埌鏈嶅姟鍣�");
+ }
+
+ TimeSpan actualTimeout = timeout ?? TimeSpan.FromSeconds(30);
+
+ if (!await _sendReceiveLock.WaitAsync(actualTimeout))
+ {
+ throw new TimeoutException("绛夊緟鍙戦�佽秴鏃�");
+ }
+
+ try
+ {
+ byte[] messageBytes = Encoding.UTF8.GetBytes(message + "\r\n");
+
+ // 鍙戦�佹秷鎭�
+ await _stream.WriteAsync(messageBytes, 0, messageBytes.Length);
+
+ // 鎺ユ敹鍝嶅簲
+ byte[] buffer = new byte[1024];
+ StringBuilder response = new StringBuilder();
+ int bytesRead;
+
+ CancellationTokenSource cts = new CancellationTokenSource(actualTimeout);
+
+ try
+ {
+ // 璇诲彇鐩村埌閬囧埌鎹㈣绗�
+ while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
+ {
+ string received = Encoding.UTF8.GetString(buffer, 0, bytesRead);
+ response.Append(received);
+
+ if (received.EndsWith("\r\n"))
+ {
+ break;
+ }
+
+ if (cts.Token.IsCancellationRequested)
+ {
+ throw new TimeoutException("鎺ユ敹鍝嶅簲瓒呮椂");
+ }
+ }
+ }
+ finally
+ {
+ cts.Dispose();
+ }
+
+ string jsonResponse = response.ToString().TrimEnd('\r', '\n');
+ Console.WriteLine($"鏀跺埌鏈嶅姟鍣ㄥ搷搴旓細{jsonResponse}");
+
+ // 鍙嶅簭鍒楀寲鍝嶅簲
+ return jsonResponse;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"鍙戦�佹秷鎭け璐ワ細{ex.Message}");
+ _isConnected = false;
+ throw;
+ }
+ finally
+ {
+ _sendReceiveLock.Release();
+ }
+ }
+
+ /// <summary>
+ /// 鍚屾鍙戦�佹秷鎭苟鎺ユ敹鍝嶅簲
+ /// </summary>
+ /// <typeparam name="T">鍝嶅簲鏁版嵁绫诲瀷</typeparam>
+ /// <param name="data">瑕佸彂閫佺殑鏁版嵁瀵硅薄</param>
+ /// <param name="timeout">瓒呮椂鏃堕棿</param>
+ /// <returns>鏈嶅姟鍣ㄥ搷搴旀暟鎹�</returns>
+ public string SendMessage(string message, TimeSpan? timeout = null)
+ {
+ timeout = timeout ?? TimeSpan.FromSeconds(30);
+
+ try
+ {
+ // 浣跨敤 Task.Run 鏉ユ墽琛屽紓姝ユ搷浣滐紝骞剁瓑寰呯粨鏋�
+ return Task.Run(() => SendMessageAsync(message, timeout)).Result;
+ }
+ catch (AggregateException ae)
+ {
+ // 瑙e寘寮傚父
+ throw ae.InnerException;
+ }
+ }
+
+ /// <summary>
+ /// 妫�鏌ユ槸鍚﹀凡杩炴帴
+ /// </summary>
+ public bool IsConnected
+ {
+ get { return _isConnected; }
+ }
+
+ /// <summary>
+ /// 閲婃斁璧勬簮
+ /// </summary>
+ public void Dispose()
+ {
+ _cts.Cancel();
+ _isConnected = false;
+ if (_stream != null)
+ {
+ _stream.Dispose();
+ }
+ if (_client != null)
+ {
+ _client.Dispose();
+ }
+ _cts.Dispose();
+ if (_sendReceiveLock != null)
+ {
+ _sendReceiveLock.Dispose();
+ }
+ }
+
+ /// <summary>
+ /// 鍏抽棴杩炴帴
+ /// </summary>
+ public void Close()
+ {
+ Dispose();
+ }
+ }
+}
--
Gitblit v1.9.1