From 5af11cc200dd5ebe474b9c0475883b0e6d1e3759 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期三, 11 三月 2026 10:00:49 +0800
Subject: [PATCH] 重构整个项目:改进代码质量和架构

---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Clients.cs |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Clients.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Clients.cs
index 9654ae2..5eb8fee 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Clients.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Clients.cs
@@ -9,6 +9,11 @@
 {
     public partial class TcpSocketServer
     {
+        /// <summary>
+        /// 检索当前在服务中注册的所有客户端标识符的只读列表。
+        /// </summary>
+        /// <remarks>返回的列表表示调用时刻客户端ID的快照。后续对客户端集合的更改不会影响返回的列表。此方法是线程安全的。</remarks>
+        /// <returns>包含客户端ID的<see cref="IReadOnlyList{String}"/>。如果没有客户端注册,列表将为空。</returns>
         public IReadOnlyList<string> GetClientIds()
         {
             lock (_syncRoot)
@@ -17,6 +22,12 @@
             }
         }
 
+        /// <summary>
+        /// 检索与指定设备标识符关联的客户端标识符。
+        /// </summary>
+        /// <remarks>此方法是线程安全的。如果未找到设备标识符,方法将返回null而不是抛出异常。</remarks>
+        /// <param name="deviceId">要检索客户端标识符的设备的唯一标识符。不能为null。</param>
+        /// <returns>与指定设备标识符关联的客户端标识符,如果不存在关联则返回null。</returns>
         public string? GetClientIdByDevice(string deviceId)
         {
             lock (_syncRoot)
@@ -25,6 +36,14 @@
             }
         }
 
+        /// <summary>
+        /// 异步向指定设备发送消息。
+        /// </summary>
+        /// <remarks>如果指定设备未注册或无法找到,则返回 <see langword="false"/>。</remarks>
+        /// <param name="deviceId">目标设备的唯一标识符。不能为null或空。</param>
+        /// <param name="message">要发送给设备的消息。不能为null。</param>
+        /// <returns>表示异步操作的任务。如果消息成功发送,任务结果为 <see langword="true"/>;
+        /// 否则为 <see langword="false"/>。</returns>
         public Task<bool> SendToDeviceAsync(string deviceId, string message)
         {
             var clientId = GetClientIdByDevice(deviceId);
@@ -32,6 +51,16 @@
             return SendToClientAsync(clientId, message);
         }
 
+        /// <summary>
+        /// 通过TCP连接异步向指定客户端发送带帧的文本消息。
+        /// </summary>
+        /// <remarks>如果客户端未连接或不存在,此方法将返回 <see langword="false"/> 且不发送消息。
+        /// 消息将优先使用客户端首选的文本编码进行编码;否则使用默认编码。
+        /// 此方法对于向不同客户端的并发调用是线程安全的。</remarks>
+        /// <param name="clientId">要发送消息到的客户端的唯一标识符。必须对应已连接的客户端。</param>
+        /// <param name="message">要发送给客户端的文本消息。不能为null。</param>
+        /// <returns>表示异步操作的任务。如果消息成功发送,任务结果为 <see langword="true"/>;
+        /// 否则,如果客户端未连接或不存在,结果为 <see langword="false"/>。</returns>
         public async Task<bool> SendToClientAsync(string clientId, string message)
         {
             TcpClient? client;
@@ -55,7 +84,8 @@
             try
             {
                 var ns = client.GetStream();
-                var data = enc.GetBytes((message ?? string.Empty) + "\n");
+                var framedMessage = BuildFramedMessage(message);
+                var data = enc.GetBytes(framedMessage);
                 await ns.WriteAsync(data, 0, data.Length);
             }
             finally
@@ -65,6 +95,13 @@
             return true;
         }
 
+        /// <summary>
+        /// 异步向所有已连接的客户端发送指定的消息。
+        /// </summary>
+        /// <remarks>如果向某个客户端发送消息时发生错误,异常将被抑制并继续向其他客户端广播。
+        /// 当所有发送操作完成后,此方法结束。</remarks>
+        /// <param name="message">要广播给所有客户端的消息。不能为null。</param>
+        /// <returns>表示异步广播操作的任务。</returns>
         public async Task BroadcastAsync(string message)
         {
             List<TcpClient> clients;
@@ -75,11 +112,19 @@
 
             await Task.WhenAll(clients.Select(c => Task.Run(async () =>
             {
-                try { await SendAsync(c, message); } catch { }
+                try { await SendMessageAsync(c, message); } catch { }
             })));
         }
 
-        public static async Task SendAsync(TcpClient client, string message)
+        /// <summary>
+        /// 通过网络流异步向指定的TCP客户端发送带帧的文本消息。
+        /// </summary>
+        /// <remarks>如果客户端为null或未连接,此方法将立即返回而不发送消息。
+        /// 消息将使用配置的文本编码进行编码并添加帧头后通过网络流发送。</remarks>
+        /// <param name="client">要发送消息到的TCP客户端。必须处于连接状态;否则方法不执行任何操作。</param>
+        /// <param name="message">要发送给客户端的文本消息。消息在传输前将被编码并添加帧头。</param>
+        /// <returns>表示异步发送操作的任务。</returns>
+        public async Task SendMessageAsync(TcpClient client, string message)
         {
             if (client == null || !client.Connected)
             {
@@ -87,7 +132,8 @@
             }
 
             NetworkStream stream = client.GetStream();
-            var data = Encoding.UTF8.GetBytes((message ?? string.Empty) + "\n");
+            var framedMessage = BuildFramedMessage(message);
+            var data = _textEncoding.GetBytes(framedMessage);
             await stream.WriteAsync(data, 0, data.Length);
         }
     }

--
Gitblit v1.9.3