/// <summary> /// Writes the data frame. /// If flow control manager has blocked stream, frames are adding to the unshippedFrames collection. /// After window update for that stream they will be delivered. /// </summary> /// <param name="data">The data.</param> /// <param name="isEndStream">if set to <c>true</c> [is fin].</param> public void WriteDataFrame(byte[] data, bool isEndStream) { var dataFrame = new DataFrame(_id, new ArraySegment <byte>(data), isEndStream); if (IsFlowControlBlocked == false) { _writeQueue.WriteFrame(dataFrame); SentDataAmount += dataFrame.FrameLength; _flowCrtlManager.DataFrameSentHandler(this, new DataFrameSentEventArgs(dataFrame)); if (dataFrame.IsEndStream) { Http2Logger.LogDebug("Transfer end"); EndStreamSent = true; } if (OnFrameSent != null) { OnFrameSent(this, new FrameSentArgs(dataFrame)); } } else { _unshippedFrames.Enqueue(dataFrame); } }
/// <summary> /// Writes the data frame. /// If flow control manager has blocked stream, frames are adding to the unshippedFrames collection. /// After window update for that stream they will be delivered. /// </summary> /// <param name="data">The data.</param> /// <param name="isEndStream">if set to <c>true</c> [is fin].</param> public void WriteDataFrame(ArraySegment <byte> data, bool isEndStream) { if (data.Array == null) { throw new ArgumentNullException("data is null"); } if (Closed) { return; } var dataFrame = new DataFrame(_id, data, isEndStream, true); Http2Logger.LogDebug( "Sending DATA frame: stream id={0}, payload len={1}, has pad={2}, pad high={3}, pad low={4}, " + "end stream={5}", dataFrame.StreamId, dataFrame.PayloadLength, dataFrame.HasPadding, dataFrame.PadHigh, dataFrame.PadLow, dataFrame.IsEndStream); //We cant let lesser frame that were passed through flow control window //be sent before greater frames that were not passed through flow control window //09 -> 6.9.1. The Flow Control Window //The sender MUST NOT //send a flow controlled frame with a length that exceeds the space //available in either of the flow control windows advertised by the receiver. if (_unshippedFrames.Count != 0 || WindowSize - dataFrame.Data.Count < 0) { _unshippedFrames.Enqueue(dataFrame); return; } if (!IsFlowControlBlocked) { _writeQueue.WriteFrame(dataFrame); SentDataAmount += dataFrame.Data.Count; _flowCrtlManager.DataFrameSentHandler(this, new DataFrameSentEventArgs(dataFrame)); if (dataFrame.IsEndStream) { Http2Logger.LogDebug("Transfer end"); Http2Logger.LogDebug("Sent bytes: {0}", SentDataAmount); HalfClosedLocal = true; } if (OnFrameSent != null) { OnFrameSent(this, new FrameSentEventArgs(dataFrame)); } } else { _unshippedFrames.Enqueue(dataFrame); } }