From e57938fbda9bff702004038f76d009422968bff5 Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期五, 06 十一月 2026 18:05:07 +0800
Subject: [PATCH] 提交代码

---
 DeviceService/ServiceManager/NamePipe/NamePipeService.cs |  424 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 424 insertions(+), 0 deletions(-)

diff --git a/DeviceService/ServiceManager/NamePipe/NamePipeService.cs b/DeviceService/ServiceManager/NamePipe/NamePipeService.cs
new file mode 100644
index 0000000..5efa826
--- /dev/null
+++ b/DeviceService/ServiceManager/NamePipe/NamePipeService.cs
@@ -0,0 +1,424 @@
+锘縰sing DeviceService.Core;
+using System.IO;
+using System.IO.Pipes;
+using System.Text.Json;
+
+namespace DeviceService.Service.NamePipe
+{
+    /// <summary>
+    /// 鍩轰簬鍛藉悕绠¢亾鐨勬湇鍔$瀹炵幇锛圡essage 妯″紡锛夈��
+    /// 鍚姩鍚庢寔缁洃鍚鎴风杩炴帴锛屾敹鍒扮殑姣忔潯娑堟伅閫氳繃 <see cref="DataReceived"/> 浜嬩欢涓婃姏锛�
+    /// 骞舵惡甯﹀彲鍥炲啓鏁版嵁鐨� <see cref="NamePipeClient"/> 瀹炰緥銆�
+    /// </summary>
+    public class NamePipeService : IService, IDisposable
+    {
+        /// <summary>榛樿鍏佽鐨勬渶澶х閬撳疄渚嬫暟锛堝嵆鏈�澶у苟鍙戣繛鎺ユ暟锛夈��</summary>
+        public const int DefaultMaxInstances = 254;
+
+        /// <summary>鍋滄鏈嶅姟鏃剁瓑寰呭悗鍙颁换鍔$粨鏉熺殑鏈�闀挎椂闂淬��</summary>
+        private static readonly TimeSpan StopTimeout = TimeSpan.FromSeconds(3);
+
+        private readonly string _pipeName;
+        private readonly int _maxInstances;
+        private readonly object _sync = new object();
+        private readonly Dictionary<NamePipeClient, Task> _clients = new Dictionary<NamePipeClient, Task>();
+
+        private CancellationTokenSource? _cts;
+        private NamedPipeServerStream? _listenStream;
+        private Task? _acceptTask;
+        private bool _running;
+        private bool _disposed;
+
+        /// <param name="pipeName">绠¢亾鍚嶇О锛屼负绌烘椂鍦� Start 闃舵鏍¢獙澶辫触銆�</param>
+        /// <param name="maxInstances">鏈�澶у苟鍙戣繛鎺ユ暟銆�</param>
+        public NamePipeService(string? pipeName = null, int maxInstances = DefaultMaxInstances)
+        {
+            if (maxInstances <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(maxInstances), "鏈�澶у疄渚嬫暟蹇呴』澶т簬 0銆�");
+            }
+            _pipeName = pipeName ?? string.Empty;
+            _maxInstances = maxInstances;
+        }
+        public event EventHandler<IClient>? ClientConnected;
+        public event EventHandler<IClient>? ClientDisConnected;
+        public event EventHandler<RequestArg>? DataReceived;
+
+        /// <summary>绠¢亾鍚嶇О銆�</summary>
+        public string PipeName => _pipeName;
+
+        /// <summary>鏈嶅姟鏄惁澶勪簬鐩戝惉鐘舵�併��</summary>
+        public bool IsRunning
+        {
+            get
+            {
+                lock (_sync)
+                {
+                    return _running;
+                }
+            }
+        }
+
+        /// <summary>褰撳墠宸茶繛鎺ョ殑瀹㈡埛绔暟閲忋��</summary>
+        public int ClientCount
+        {
+            get
+            {
+                lock (_sync)
+                {
+                    return _clients.Count;
+                }
+            }
+        }
+
+        public bool Start(out string msg)
+        {
+            lock (_sync)
+            {
+                if (_disposed)
+                {
+                    msg = "鏈嶅姟宸查噴鏀撅紝鏃犳硶鍚姩銆�";
+                    return false;
+                }
+
+                if (_running)
+                {
+                    msg = "鏈嶅姟宸插浜庤繍琛岀姸鎬併��";
+                    return false;
+                }
+
+                if (string.IsNullOrWhiteSpace(_pipeName))
+                {
+                    msg = "绠¢亾鍚嶇О鏈缃紝鏃犳硶鍚姩銆�";
+                    return false;
+                }
+
+                NamedPipeServerStream listenStream;
+                try
+                {
+                    listenStream = CreatePipeStream();
+                }
+                catch (Exception ex)
+                {
+                    msg = $"鍒涘缓鍛藉悕绠¢亾 \"{_pipeName}\" 澶辫触锛歿ex.Message}";
+                    return false;
+                }
+
+                var cts = new CancellationTokenSource();
+                _cts = cts;
+                _listenStream = listenStream;
+                _running = true;
+                _acceptTask = Task.Run(() => AcceptLoopAsync(listenStream, cts.Token));
+            }
+
+            msg = $"鍛藉悕绠¢亾 \"{_pipeName}\" 宸插惎鍔ㄧ洃鍚��";
+            return true;
+        }
+
+        public bool Stop(out string msg)
+        {
+            Task? acceptTask;
+            List<Task> clientTasks = new List<Task>();
+
+            lock (_sync)
+            {
+                if (!_running)
+                {
+                    msg = "鏈嶅姟鏈繍琛屻��";
+                    return false;
+                }
+
+                _running = false;
+                acceptTask = _acceptTask;
+                _acceptTask = null;
+
+                try
+                {
+                    _cts?.Cancel();
+                }
+                catch
+                {
+                    // 蹇界暐鍙栨秷杩囩▼涓殑寮傚父
+                }
+
+                try
+                {
+                    _listenStream?.Dispose();
+                }
+                catch
+                {
+                    // 蹇界暐鍏抽棴鐩戝惉娴佺殑寮傚父
+                }
+
+                _listenStream = null;
+
+                // 鍏抽棴鎵�鏈夊鎴风杩炴帴锛屼娇闃诲涓殑璇诲彇绔嬪嵆缁撴潫
+                foreach (KeyValuePair<NamePipeClient, Task> item in _clients)
+                {
+                    try
+                    {
+                        item.Key.Dispose();
+                    }
+                    catch
+                    {
+                        // 蹇界暐鍗曚釜杩炴帴鐨勫叧闂紓甯�
+                    }
+
+                    clientTasks.Add(item.Value);
+                }
+
+                _clients.Clear();
+
+                _cts?.Dispose();
+                _cts = null;
+            }
+
+            try
+            {
+                acceptTask?.Wait(StopTimeout);
+                if (clientTasks.Count > 0)
+                {
+                    Task.WaitAll(clientTasks.ToArray(), StopTimeout);
+                }
+            }
+            catch (AggregateException)
+            {
+                // 鍚庡彴浠诲姟鍦ㄦ牎楠�/鍙栨秷闃舵鎶涘嚭鐨勫紓甯告棤闇�鍚戜笂浼犳挱
+            }
+
+            msg = "鏈嶅姟宸插仠姝€��";
+            return true;
+        }
+
+        private NamedPipeServerStream CreatePipeStream()
+        {
+            var pipe = new NamedPipeServerStream(
+                _pipeName,
+                PipeDirection.InOut,
+                _maxInstances,
+                PipeTransmissionMode.Message,
+                PipeOptions.Asynchronous);
+            pipe.ReadMode = PipeTransmissionMode.Message;
+            return pipe;
+        }
+
+        /// <summary>
+        /// 杩炴帴鎺ュ彈寰幆锛氭瘡鎺ュ彈涓�涓繛鎺ュ氨浜ょ粰鐙珛鐨勫鐞嗕换鍔★紝骞跺噯澶囦笅涓�涓閬撳疄渚嬬户缁洃鍚��
+        /// </summary>
+        private async Task AcceptLoopAsync(NamedPipeServerStream initial, CancellationToken token)
+        {
+            NamedPipeServerStream? listenStream = initial;
+            try
+            {
+                while (!token.IsCancellationRequested)
+                {
+                    NamedPipeServerStream stream = listenStream!;
+                    listenStream = null;
+
+                    try
+                    {
+                        await stream.WaitForConnectionAsync(token).ConfigureAwait(false);
+                    }
+                    catch (OperationCanceledException)
+                    {
+                        stream.Dispose();
+                        break;
+                    }
+                    catch (ObjectDisposedException)
+                    {
+                        break;
+                    }
+                    catch (IOException)
+                    {
+                        stream.Dispose();
+                        break;
+                    }
+
+                    // .NET Framework 涓� WaitForConnectionAsync 鍙兘鎻愬墠杩斿洖锛屾澶勬牎楠岃繛鎺ョ‘瀹炲缓绔�
+                    if (!stream.IsConnected)
+                    {
+                        try
+                        {
+                            await Task.Delay(50, token).ConfigureAwait(false);
+                        }
+                        catch (OperationCanceledException)
+                        {
+                            break;
+                        }
+
+                        listenStream = stream;
+                        continue;
+                    }
+
+                    var client = new NamePipeClient(stream);
+                    Task handler = Task.Run(() => HandleClientAsync(client, token));
+                    RegisterClient(client, handler);
+
+                    // 涓轰笅涓�涓繛鎺ュ噯澶囨柊鐨勭閬撳疄渚�
+                    try
+                    {
+                        listenStream = CreatePipeStream();
+                    }
+                    catch (Exception)
+                    {
+                        break;
+                    }
+
+                    lock (_sync)
+                    {
+                        if (!_running)
+                        {
+                            break;
+                        }
+
+                        _listenStream = listenStream;
+                    }
+                }
+            }
+            catch (Exception)
+            {
+                // 鐩戝惉寰幆涓殑鏈煡寮傚父鐩存帴缁撴潫寰幆锛岀敱 Stop 璐熻矗鏀跺熬
+            }
+            finally
+            {
+                try
+                {
+                    listenStream?.Dispose();
+                }
+                catch
+                {
+                    // 蹇界暐鍏抽棴寮傚父
+                }
+
+                lock (_sync)
+                {
+                    _listenStream = null;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 鍗曚釜杩炴帴鐨勮鍙栧惊鐜細鎸夎璇诲彇娑堟伅骞惰Е鍙� <see cref="DataReceived"/>銆�
+        /// </summary>
+        private async Task HandleClientAsync(NamePipeClient client, CancellationToken token)
+        {
+            OnClientEvent(ClientConnected, client);
+            try
+            {
+                while (!token.IsCancellationRequested)
+                {
+                    string? message = await client.ReadMessageAsync().ConfigureAwait(false);
+                    if (message == null)
+                    {
+                        break;
+                    }
+
+                    RaiseDataReceived(client, message);
+                }
+            }
+            catch (OperationCanceledException)
+            {
+                // 鏈嶅姟鍋滄瀵艰嚧鐨勬甯稿彇娑�
+            }
+            catch (Exception)
+            {
+                // 杩炴帴鏂紑銆佹暟鎹潪娉曠瓑鎯呭喌鐩存帴缁撴潫璇ヨ繛鎺ョ殑璇诲彇
+            }
+            finally
+            {
+                OnClientEvent(ClientDisConnected, client);
+                UnregisterClient(client);
+                client.Dispose();
+            }
+        }
+
+        private void OnClientEvent(EventHandler<IClient>? handler, IClient client)
+        {
+            if (handler == null)
+            {
+                return;
+            }
+
+            try
+            {
+                handler(this, client);
+            }
+            catch
+            {
+                // 璁㈤槄鏂圭殑寮傚父涓嶅簲褰卞搷杩炴帴鐨勫缓绔嬩笌閲婃斁
+            }
+        }
+
+        private void RaiseDataReceived(NamePipeClient client, string raw)
+        {
+            var data = JsonSerializer.Deserialize<RequestData>(raw);
+            var arg = new RequestArg
+            {
+                Data = data,
+                Raw = raw,
+                Client = client
+            };
+            OnDataReceived(arg);
+        }
+
+        private void RegisterClient(NamePipeClient client, Task handler)
+        {
+            lock (_sync)
+            {
+                if (_running)
+                {
+                    _clients[client] = handler;
+                    return;
+                }
+            }
+
+            // 鏈嶅姟姝e湪鍋滄锛岀洿鎺ラ噴鏀捐杩炴帴
+            client.Dispose();
+        }
+
+        private void UnregisterClient(NamePipeClient client)
+        {
+            lock (_sync)
+            {
+                _clients.Remove(client);
+            }
+        }
+
+        private void OnDataReceived(RequestArg arg)
+        {
+            EventHandler<RequestArg>? handler = DataReceived;
+            if (handler == null)
+            {
+                return;
+            }
+
+            try
+            {
+                handler?.Invoke(this, arg);
+            }
+            catch
+            {
+                // 璁㈤槄鏂圭殑寮傚父涓嶅簲涓柇绠¢亾璇诲彇
+            }
+        }
+
+        public void Dispose()
+        {
+            if (_disposed)
+            {
+                return;
+            }
+
+            try
+            {
+                Stop(out _);
+            }
+            catch
+            {
+                // 閲婃斁闃舵鐨勫紓甯稿拷鐣�
+            }
+
+            _disposed = true;
+        }
+    }
+}

--
Gitblit v1.9.1