wangxinhui
2026-02-27 804051e9e3013a3ad6b3e47757050e32893cf4fb
´úÂë¹ÜÀí/WCS/WCSServers/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs
@@ -16,20 +16,81 @@
    public partial class TcpSocketServer : IDisposable
    {
        private readonly SocketServerOptions _options;
        /// <summary>
        /// æä¾›ä¸€ä¸ªå¯ç”¨äºŽåŒæ­¥å¯¹åŒ…含实例的访问的对象。
        /// </summary>
        /// <remarks>在对实例实现线程安全操作时,可将此对象用作锁定目标。此模式通常用于避免死锁并确保一致的同步。</remarks>
        public readonly object _syncRoot = new();
        private TcpListener? _listener;
        /// <summary>
        /// è¡¨ç¤ºç”¨äºŽå‘出进行中操作的取消请求的取消令牌源。
        /// </summary>
        /// <remarks>如果当前没有活动的取消机制,此字段可能为null。使用此令牌源取消支持取消的任务或操作。</remarks>
        public CancellationTokenSource? _cts;
        /// <summary>
        /// æä¾›è¡¨ç¤ºæ´»åŠ¨å®¢æˆ·ç«¯æ“ä½œçš„ä»»åŠ¡åˆ—è¡¨ã€‚
        /// </summary>
        /// <remarks>此字段用于内部跟踪异步客户端活动。它是只读的,不应在包含类外部直接修改。</remarks>
        public readonly List<Task> _clientTasks = new();
        /// <summary>
        /// æä¾›ä»Žå®¢æˆ·ç«¯æ ‡è¯†ç¬¦åˆ°å…¶å…³è”çš„TCP客户端连接的映射。
        /// </summary>
        /// <remarks>此字典允许通过唯一字符串标识符访问活动的TCP客户端。在多线程场景中,对集合的修改应小心进行以避免并发问题。</remarks>
        public readonly Dictionary<string, TcpClient> _clients = new();
        /// <summary>
        /// æä¾›ä»Žè®¾å¤‡æ ‡è¯†ç¬¦åˆ°å…¶å¯¹åº”绑定值的映射。
        /// </summary>
        /// <remarks>此字段是只读的,用于包含类内部使用。应通过指定的方法或属性对字典进行修改以确保一致性。</remarks>
        public readonly Dictionary<string, string> _deviceBindings = new();
        /// <summary>
        /// æä¾›ä»Žå®¢æˆ·ç«¯æ ‡è¯†ç¬¦åˆ°å…¶å…³è”锁的映射,用于同步对客户端特定资源的访问。
        /// </summary>
        /// <remarks>字典中的每个条目将一个唯一的客户端ID与一个<see cref="SemaphoreSlim"/>实例关联,实现每个客户端的线程安全操作。此集合用于内部协调并发访问,不应直接修改。</remarks>
        public readonly Dictionary<string, SemaphoreSlim> _clientLocks = new();
        /// <summary>
        /// æä¾›ä»Žå®¢æˆ·ç«¯æ ‡è¯†ç¬¦åˆ°å…¶å…³è”文本编码的映射。
        /// </summary>
        /// <remarks>此字典用于内部跟踪已连接客户端的编码偏好。键表示客户端标识符,值指定用于文本操作的对应<see cref="System.Text.Encoding"/>。</remarks>
        public readonly Dictionary<string, Encoding> _clientEncodings = new();
        /// <summary>
        /// å­˜å‚¨æ¯ä¸ªå®¢æˆ·ç«¯æœ€åŽæ´»åŠ¨çš„æ—¶é—´æˆ³ï¼Œä»¥å®¢æˆ·ç«¯æ ‡è¯†ç¬¦ä¸ºé”®ã€‚
        /// </summary>
        /// <remarks>此字段用于内部跟踪客户端活动。字典将客户端标识符映射到对应的最后活动时间(UTC)。直接修改此集合可能影响客户端会话管理逻辑。</remarks>
        public readonly Dictionary<string, DateTime> _clientLastActive = new();
        /// <summary>
        /// æŒ‡å®šåŒ…含类型中字符数据使用的文本编码。
        /// </summary>
        /// <remarks>使用此字段确定处理字符数据时如何编码或解码文本。编码影响字节如何被解释为字符,反之亦然。常见的编码包括UTF8、ASCII和Unicode。</remarks>
        public readonly Encoding _textEncoding;
        /// <summary>
        /// è¡¨ç¤ºè‡ªåŠ¨æ£€æµ‹åˆ°çš„GB2312编码(如果可用)。
        /// </summary>
        /// <remarks>通常从输入数据确定编码时设置此字段。如果检测失败或未执行检测,值可能为null。</remarks>
        public readonly Encoding? _autoDetectedGb2312;
        private readonly string _logFile;
        private Task? _monitorTask;
        /// <summary>
        /// ä½¿ç”¨æŒ‡å®šçš„æœåŠ¡å™¨é€‰é¡¹åˆå§‹åŒ– TcpSocketServer ç±»çš„æ–°å®žä¾‹ã€‚
        /// </summary>
        /// <remarks>如果启用了 AutoDetectEncoding é€‰é¡¹ï¼ŒæœåŠ¡å™¨å°†é»˜è®¤ä½¿ç”¨ UTF-8 ç¼–码,
        /// å¹¶å°è¯•支持 GBK ç¼–码进行自动检测。如果编码检测失败或提供了无效的编码名称,
        /// å°†å›žé€€ä½¿ç”¨ UTF-8 ç¼–码。日志文件路径由 LogFilePath é€‰é¡¹å†³å®šï¼Œ
        /// å¦‚果未指定,则默认为应用程序基目录下的 'socketserver.log' æ–‡ä»¶ã€‚</remarks>
        /// <param name="options">套接字服务器的配置选项。不能为 null。提供编码设置、日志文件路径和自动检测行为等配置。</param>
        public TcpSocketServer(IOptions<SocketServerOptions> options)
        {
            _options = options.Value;
@@ -51,7 +112,8 @@
        public bool IsRunning { get; private set; }
        public event Func<string, bool, TcpClient, RobotSocketState, Task<string?>>? MessageReceived;
        public event Func<string, bool, TcpClient, StackerSocketState, Task<string?>>? MessageReceived;
        public event Func<string, Task<string?>>? RobotReceived;
        private void Log(string message)