private Task ForwardFromProviderAsync(LogInfo logInfo) => this.ForwardAsync( this.ProviderConnection, this.ConsumerConnection, logInfo, ShortProviderToConsumer, ProviderToConsumer);
private async Task ForwardAsync( ConnectionViewModel readConnection, ConnectionViewModel writeConnection, LogInfo logInfo, string shortDirection, string direction) { var payloadStream = new MemoryStream(); var buffer = new byte[8192]; var s101Reader = new S101Reader( (b, o, c, t) => this.ForwardBytesAsync(logInfo, direction, readConnection, writeConnection, b, o, c, t)); Func <LogInfo, OutOfFrameByteReceivedEventArgs, EventInfo> logOutOfFrame = (i, e) => i.Logger.LogData("OutOfFrameByte", direction, new[] { e.Value }, 0, 1); EventHandler <OutOfFrameByteReceivedEventArgs> handler = async(s, e) => await this.EnqueueLogOperationAsync(logInfo, "OOFB", shortDirection, null, i => logOutOfFrame(i, e)); try { s101Reader.OutOfFrameByteReceived += handler; while (await s101Reader.ReadAsync(CancellationToken.None)) { payloadStream.SetLength(0); int read; while ((read = await s101Reader.Payload.ReadAsync(buffer, 0, buffer.Length)) > 0) { payloadStream.Write(buffer, 0, read); } var type = GetShortType(s101Reader.Message.Command.ToString()); var message = s101Reader.Message; var payload = payloadStream.ToArray(); var length = payload.Length; if (length > 0) { await this.logQueue.Enqueue( () => Task.Run(() => logInfo.Logger.LogData("DecodedPayload", direction, payload, 0, length))); } await this.EnqueueLogOperationAsync( logInfo, type, shortDirection, length, i => i.Logger.LogMessage(direction, message, payload)); } await s101Reader.DisposeAsync(CancellationToken.None); } catch (ObjectDisposedException) { } catch (Exception ex) { await this.EnqueueLogOperationAsync( logInfo, "Exception", shortDirection, null, i => i.Logger.LogException(direction, ex)); } finally { s101Reader.OutOfFrameByteReceived -= handler; payloadStream.Dispose(); writeConnection.Client.Close(); readConnection.Client.Close(); } }
private async Task ForwardLoop(TcpListener listener) { while (this.IsStarted && !this.IsStopped) { if (listener.Pending()) { ++this.ConsumerConnection.ConnectionCountCore; string logPath; while (File.Exists(logPath = this.GetLogFilename())) { await Task.Delay(1000); } var logInfo = new LogInfo(logPath); try { ++this.ProviderConnection.ConnectionCountCore; this.ProviderConnection.Client = await this.ConnectToProvider(); try { this.ConsumerConnection.Client = await listener.AcceptTcpClientAsync(); listener.Stop(); await Task.WhenAll( this.ForwardFromConsumerAsync(logInfo), this.ForwardFromProviderAsync(logInfo)); } catch (Exception ex) { listener.Stop(); await this.EnqueueLogOperationAsync( logInfo, "Exception", null, null, i => i.Logger.LogException("Consumer to Proxy", ex)); } if (this.ConsumerConnection.Client != null) { this.ConsumerConnection.Client.Close(); this.ConsumerConnection.Client = null; } } catch (Exception ex) { listener.Stop(); await this.EnqueueLogOperationAsync( logInfo, "Exception", null, null, i => i.Logger.LogException("Proxy to Provider", ex)); } if (this.ProviderConnection.Client != null) { this.ProviderConnection.Client.Close(); this.ProviderConnection.Client = null; } Func <LogInfo, EventInfo> operation = i => { i.Dispose(); return(default(EventInfo)); }; await this.EnqueueLogOperationAsync(logInfo, null, null, null, operation); listener.Start(1); } else { await Task.Delay(500); } } }