async Task PipeA2B(CancellationToken cancellationToken) { //using (var received = SmartBuffer.Rent(_bufferSize)) var received = SmartBuffer.Rent(_bufferSize); while (!cancellationToken.IsCancellationRequested) { received.SignificantLength = await ClientA.ReadAsync(received.Memory, cancellationToken); _logger.LogInformation($"Received {received.SignificantLength} bytes from [{ClientA.EndPoint.ToString()}]."); if (0 >= received.SignificantLength) { ReportBroken(PipeBrokenCause.Exception); return; } if (_filtersA.Count > 0) { var result = ExecuteFilter_AfterReading(ClientA, received, _filtersA, cancellationToken); received.Dispose(); received = result.Buffer; if (!result.Continue) { _logger.LogInformation($"Ripe broke by filterA [{ClientA.EndPoint.ToString()}]."); received?.Dispose(); ReportBroken(PipeBrokenCause.FilterBreak); return; } } if (_filtersB.Count > 0) { var result = ExecuteFilter_BeforeWriting(ClientB, received, _filtersB, cancellationToken); received.Dispose(); received = result.Buffer; if (!result.Continue) { _logger.LogInformation($"Ripe broke by filterB [{ClientB.EndPoint.ToString()}]."); received?.Dispose(); ReportBroken(PipeBrokenCause.FilterBreak); return; } } if (null != received && received.SignificantLength > 0) { _logger?.LogInformation($"{received.SignificantLength} bytes left after filtering."); int written = await ClientB.WriteAsync(received.SignificanMemory, cancellationToken); _logger?.LogInformation($"Pipe [{ClientA.EndPoint.ToString()}] => [{ClientB.EndPoint.ToString()}] {written} bytes."); if (0 >= written) { received?.Dispose(); ReportBroken(PipeBrokenCause.Exception); return; } ReportPiping(new PipingEventArgs { Bytes = written, Origin = ClientA.EndPoint, Destination = ClientB.EndPoint }); } //continue piping }//end while received?.Dispose(); ReportBroken(PipeBrokenCause.Cancelled); }
async Task PipeA2B(CancellationToken cancellationToken) { SmartBuffer buffer = SmartBuffer.Rent(_bufferSize); buffer.SignificantLength = await ClientA.ReadAsync(buffer.Memory, cancellationToken); if (buffer.SignificantLength > 0) { if (_filtersA.Count > 0) { bool locked = false; try { DoFilter_Lock(ref locked); PipeFilterResult filterResult = DoFilter_AfterReading(ref buffer, _filtersA, cancellationToken); if (!filterResult.Continue || cancellationToken.IsCancellationRequested) { ReportBroken(); return; } else { buffer = filterResult.Buffer; } DoFilter_UnLock(ref locked); } finally { DoFilter_UnLock(ref locked); } }//end FilterA if (_filtersB.Count > 0) { bool locked = false; try { DoFilter_Lock(ref locked); PipeFilterResult filterResult = DoFilter_BeforeWriting(ref buffer, _filtersB, cancellationToken); if (!filterResult.Continue || cancellationToken.IsCancellationRequested) { ReportBroken(); return; } else { buffer = filterResult.Buffer; } DoFilter_UnLock(ref locked); } finally { DoFilter_UnLock(ref locked); } }//end FilterB int written = await ClientB.WriteAsync(buffer.Memory, cancellationToken); _logger?.LogInformation($"DefaultPipe Pipe A to B {written} bytes."); if (written < 0) { //ClientB.Close(); buffer.Dispose(); ReportBroken(); return; } } else if (0 == buffer.SignificantLength) { _logger?.LogInformation($"DefaultPipe read = 0."); } else//<0 { _logger?.LogInformation($"DefaultPipe error, read={buffer.SignificantLength}."); ClientA.Close(); ReportBroken(); return; } buffer.Dispose(); if (!cancellationToken.IsCancellationRequested) { await PipeA2B(cancellationToken);//continue. } }