using System; using System.Collections.Concurrent; using System.IO; using System.IO.Pipes; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConnectionUtil { public static class PipeStreamUtil { public static string ReadMessage(this PipeStream ps) { MemoryStream ms = new MemoryStream(); byte[] buffer = new byte[0x1000]; do { ms.Write(buffer, 0, ps.Read(buffer, 0, buffer.Length)); } while (!ps.IsMessageComplete); return Encoding.UTF8.GetString(ms.ToArray()); } public static void WriteMessage(this PipeStream ps, string message) { var msg = Encoding.UTF8.GetBytes(message); ps.Write(msg, 0, msg.Length); ps.Flush(); } } public class PipeServer2 : IDisposable { private readonly string _pipeName; private readonly int _maxNumberOfServerInstances; private readonly CancellationTokenSource _cancellationTokenSource; private readonly ConcurrentDictionary _activeConnections; private readonly ReaderWriterLockSlim _lock; private bool _isDisposed; private bool _isRunning; // 事件定义 public event EventHandler OnData; public event EventHandler OnClientConnected; public event EventHandler OnClientDisconnected; public event EventHandler OnError; public PipeServer2(string pipeName, int maxNumberOfServerInstances = 254) { _pipeName = pipeName; _maxNumberOfServerInstances = maxNumberOfServerInstances; _cancellationTokenSource = new CancellationTokenSource(); _activeConnections = new ConcurrentDictionary(); _lock = new ReaderWriterLockSlim(); } public void Start() { if (_isRunning) return; _isRunning = true; Task.Run(() => { while (_isRunning && !_cancellationTokenSource.Token.IsCancellationRequested) { try { var pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.InOut, _maxNumberOfServerInstances , PipeTransmissionMode.Message); pipeServer.WaitForConnection(); string clientId = Guid.NewGuid().ToString(); if (_activeConnections.TryAdd(clientId, pipeServer)) { // 启动处理客户端消息的线程 Thread clientThread = new Thread(() => HandleClient(clientId, pipeServer)); clientThread.Start(); OnClientConnected?.Invoke(this, new PipeConnectionEventArgs(clientId)); } } catch (Exception ex) { OnError?.Invoke(this, new PipeErrorEventArgs("Connect", ex)); Thread.Sleep(1000); // 发生错误时等待一秒再重试 } } }); } private void HandleClient(string clientId, NamedPipeServerStream pipeServer) { try { while (!_cancellationTokenSource.Token.IsCancellationRequested) { try { // 等待客户端发送消息 string message = pipeServer.ReadMessage(); if (string.IsNullOrEmpty(message)) break; OnData?.Invoke(this, new PipeDataEventArgs(clientId, message)); } catch (Exception ex) { OnError?.Invoke(this, new PipeErrorEventArgs("HandleClientMessageError", ex)); break; } } } finally { if (_activeConnections.TryRemove(clientId, out var pipe)) { pipe.Dispose(); } OnClientDisconnected?.Invoke(this, new PipeConnectionEventArgs(clientId)); } } public void SendMessage(string clientId, string message) { if (!_activeConnections.TryGetValue(clientId, out var pipeServer)) { throw new InvalidOperationException($"找不到客户端 {clientId}"); } _lock.EnterWriteLock(); try { try { pipeServer.WriteMessage(message); } catch (Exception ex) { OnError?.Invoke(this, new PipeErrorEventArgs($"向客户端 {clientId} 发送消息时发生错误", ex)); } } finally { _lock.ExitWriteLock(); } } public void BroadcastMessage(string message) { _lock.EnterWriteLock(); try { foreach (var pipeServer in _activeConnections.Values) { pipeServer.WriteMessage(message); } } finally { _lock.ExitWriteLock(); } } public void Stop() { _isRunning = false; _cancellationTokenSource.Cancel(); } public void Dispose() { if (!_isDisposed) { Stop(); foreach (var pipeServer in _activeConnections.Values) { pipeServer.Dispose(); } _activeConnections.Clear(); _cancellationTokenSource.Dispose(); _lock.Dispose(); _isDisposed = true; } } } }