using DeviceService.Core; using System.IO; using System.IO.Pipes; using System.Text.Json; namespace DeviceService.Service.NamePipe { /// /// 基于命名管道的服务端实现(Message 模式)。 /// 启动后持续监听客户端连接,收到的每条消息通过 事件上抛, /// 并携带可回写数据的 实例。 /// public class NamePipeService : IService, IDisposable { /// 默认允许的最大管道实例数(即最大并发连接数)。 public const int DefaultMaxInstances = 254; /// 停止服务时等待后台任务结束的最长时间。 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 _clients = new Dictionary(); private CancellationTokenSource? _cts; private NamedPipeServerStream? _listenStream; private Task? _acceptTask; private bool _running; private bool _disposed; /// 管道名称,为空时在 Start 阶段校验失败。 /// 最大并发连接数。 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? ClientConnected; public event EventHandler? ClientDisConnected; public event EventHandler? DataReceived; /// 管道名称。 public string PipeName => _pipeName; /// 服务是否处于监听状态。 public bool IsRunning { get { lock (_sync) { return _running; } } } /// 当前已连接的客户端数量。 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 clientTasks = new List(); 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 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; } /// /// 连接接受循环:每接受一个连接就交给独立的处理任务,并准备下一个管道实例继续监听。 /// 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; } } } /// /// 单个连接的读取循环:按行读取消息并触发 。 /// 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? handler, IClient client) { if (handler == null) { return; } try { handler(this, client); } catch { // 订阅方的异常不应影响连接的建立与释放 } } private void RaiseDataReceived(NamePipeClient client, string raw) { var data = JsonSerializer.Deserialize(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; } } // 服务正在停止,直接释放该连接 client.Dispose(); } private void UnregisterClient(NamePipeClient client) { lock (_sync) { _clients.Remove(client); } } private void OnDataReceived(RequestArg arg) { EventHandler? handler = DataReceived; if (handler == null) { return; } try { handler?.Invoke(this, arg); } catch { // 订阅方的异常不应中断管道读取 } } public void Dispose() { if (_disposed) { return; } try { Stop(out _); } catch { // 释放阶段的异常忽略 } _disposed = true; } } }