using global::System.IO.Pipes; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace Pilz.IO; public class ManagedPipeServer : ManagedPipe { // Pro Verbindung (Anfrage) wird ein Client-Objekt generiert, das den Datenaustausch dieser Verbindung abwickelt public List Clients { get; private set; } = new List(); private readonly string pipeName = ""; private readonly int maxNumbersOfServerInstances; private int numberOfStartedServerInstances = 0; public ManagedPipeServer(string pipeName) : this(pipeName, 1) { } public ManagedPipeServer(string pipeName, int maxNumbersOfServerInstances) { this.pipeName = pipeName; this.maxNumbersOfServerInstances = maxNumbersOfServerInstances; CreateWaitingStream(); } private void CreateWaitingStream() { if (numberOfStartedServerInstances < maxNumbersOfServerInstances) { var strm = new NamedPipeServerStream(pipeName, PipeDirection.InOut, maxNumbersOfServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); numberOfStartedServerInstances += 1; strm.BeginWaitForConnection(EndAccept, strm); } } private void EndAccept(IAsyncResult ar) { NamedPipeServerStream strm = (NamedPipeServerStream)ar.AsyncState; strm.EndWaitForConnection(ar); if (IsDisposed) { strm.Dispose(); return; } { var withBlock = new ManagedPipeClient(strm); withBlock.RetriveData += Client_RetriveData; withBlock.StatusMessage += Client_StatusMessage; withBlock.Disposed += Client_Disposed; withBlock.AddTo(Clients); } CreateWaitingStream(); } /* TODO ERROR: Skipped RegionDirectiveTrivia */ private void Client_Disposed(ManagedPipe Sender) { // den Client für die beendete Verbindung entfernen Sender.RemoveFrom(Clients); numberOfStartedServerInstances -= 1; CreateWaitingStream(); } private void Client_RetriveData(object sender, DataEventArgs e) { // einkommende ChatMessages anzeigen, und an alle versenden OnRetriveData(e); } private void Client_StatusMessage(object sender, DataEventArgs e) { // einkommende StatusMessages durchreichen (zur Anzeige) OnStatusMessage(e); } /* TODO ERROR: Skipped EndRegionDirectiveTrivia */ public override Task SendAsnyc(byte[] bytes) { return Task.Run(() => Send(bytes)); } public override void Send(byte[] data) { foreach (ManagedPipeClient client in Clients) // an alle versenden client.Send(data); } protected override void Dispose(bool disposing) { if (numberOfStartedServerInstances < maxNumbersOfServerInstances) { using (var clnt = new NamedPipeClientStream(pipeName)) { // Herstellen einer Dummi-Verbindung, damit der ServerStream aus dem Wartezustand herauskommt. clnt.Connect(); } } for (int i = Clients.Count - 1; i >= 0; i -= 1) Clients[i].Dispose(); } }