public override async Task DoReceiveMessageAsync() { // TODO find zero-copy way, use same buffer // receive bytes var bytesRecv = new byte[256]; var buf = AlternativeCompositeByteBuf.CompBuffer(); var stream = _tcpClient.GetStream(); var pieceCount = 0; do { Array.Clear(bytesRecv, 0, bytesRecv.Length); buf.Clear(); int nrBytes; try { nrBytes = await stream.ReadAsync(bytesRecv, 0, bytesRecv.Length).WithCancellation(CloseToken); } catch (OperationCanceledException) { // the socket has been closed return; } buf.WriteBytes(bytesRecv.ToSByteArray(), 0, nrBytes); var localEp = (IPEndPoint)Socket.LocalEndPoint; RemoteEndPoint = (IPEndPoint)Socket.RemoteEndPoint; var piece = new StreamPiece(buf, localEp, RemoteEndPoint); Logger.Debug("[{0}] Received {1}. {2} : {3}", ++pieceCount, piece, Convenient.ToHumanReadable(nrBytes), Convenient.ToString(bytesRecv)); // execute inbound pipeline, per piece (reset session!) if (Session.IsTimedOut) { return; } Session.Read(piece); Session.Reset(); } while (!IsClosed && stream.DataAvailable && !Session.IsTimedOut); }
protected override async Task ProcessRequestAsync(object state) { var client = (TcpClient) state; var stream = client.GetStream(); object readRes; var pieceCount = 0; // prepare new session var recvBuffer = new byte[256]; var buf = AlternativeCompositeByteBuf.CompBuffer(); var session = Pipeline.CreateNewServerSession(this); session.TriggerActive(); // process content do { // TODO find zero-copy way, use same buffer Array.Clear(recvBuffer, 0, recvBuffer.Length); buf.Clear(); var nrBytes = await stream.ReadAsync(recvBuffer, 0, recvBuffer.Length); buf.WriteBytes(recvBuffer.ToSByteArray(), 0, nrBytes); var localEp = (IPEndPoint) client.Client.LocalEndPoint; var remoteEp = (IPEndPoint) client.Client.RemoteEndPoint; var piece = new StreamPiece(buf, localEp, remoteEp); Logger.Debug("[{0}] Received {1}. {2} : {3}", ++pieceCount, piece, Convenient.ToHumanReadable(nrBytes), Convenient.ToString(recvBuffer)); // execute inbound pipeline, per piece readRes = session.Read(piece); // resets timeout session.Reset(); // resets session internals } while (!IsClosed && stream.DataAvailable && !session.IsTimedOut); if (session.IsTimedOut) { session.TriggerInactive(); return; } // execute outbound pipeline var writeRes = session.Write(readRes); // resets timeout if (session.IsTimedOut) { session.TriggerInactive(); return; } // send back var bytes = ConnectionHelper.ExtractBytes(writeRes); await stream.WriteAsync(bytes, 0, bytes.Length); NotifyWriteCompleted(); // resets timeout Logger.Debug("Sent {0} : {1}", Convenient.ToHumanReadable(bytes.Length), Convenient.ToString(bytes)); session.TriggerInactive(); }