public Http2Session(Stream stream, ConnectionEnd end, bool usePriorities, bool useFlowControl, bool isSecure, CancellationToken cancel, int initialWindowSize = Constants.InitialFlowControlWindowSize, int maxConcurrentStreams = Constants.DefaultMaxConcurrentStreams) { if (stream == null) throw new ArgumentNullException("stream is null"); if (cancel == null) throw new ArgumentNullException("cancellation token is null"); if (maxConcurrentStreams <= 0) throw new ArgumentOutOfRangeException("maxConcurrentStreams cant be less or equal then 0"); if (initialWindowSize <= 0 && useFlowControl) throw new ArgumentOutOfRangeException("initialWindowSize cant be less or equal then 0"); _ourEnd = end; _usePriorities = usePriorities; _useFlowControl = useFlowControl; _isSecure = isSecure; _cancelSessionToken = cancel; if (_ourEnd == ConnectionEnd.Client) { _remoteEnd = ConnectionEnd.Server; _lastId = -1; // Streams opened by client are odd //if we got unsecure connection then server will respond with id == 1. We cant initiate //new stream with id == 1. if (!(stream is SslStream)) { _lastId = 3; } } else { _remoteEnd = ConnectionEnd.Client; _lastId = 0; // Streams opened by server are even } _goAwayReceived = false; _comprProc = new CompressionProcessor(_ourEnd); _ioStream = stream; _frameReader = new FrameReader(_ioStream); ActiveStreams = new ActiveStreams(); _writeQueue = new WriteQueue(_ioStream, ActiveStreams, _comprProc, _usePriorities); OurMaxConcurrentStreams = maxConcurrentStreams; RemoteMaxConcurrentStreams = maxConcurrentStreams; InitialWindowSize = initialWindowSize; _flowControlManager = new FlowControlManager(this); if (!_useFlowControl) { _flowControlManager.Options = (byte) FlowControlOptions.DontUseFlowControl; } SessionWindowSize = 0; _headersSequences = new HeadersSequenceList(); _promisedResources = new Dictionary<int, string>(); }
private void Close(ResetStatusCode status) { if (_disposed) return; Http2Logger.LogDebug("Session closing"); _disposed = true; // Dispose of all streams foreach (var stream in ActiveStreams.Values) { //Cancel all opened streams stream.Dispose(ResetStatusCode.Cancel); } if (!_goAwayReceived) WriteGoAway(status); OnSettingsSent = null; OnFrameReceived = null; //Missing GoAway means connection was forcibly closed by the remote ep. This means that we can //send nothing into this connection. No need trying to send GoAway. //Hence we may not check for !_goAwayReceived if (_writeQueue != null) { _writeQueue.Flush(); _writeQueue.Dispose(); } if (_frameReader != null) { _frameReader.Dispose(); _frameReader = null; } if (_comprProc != null) { _comprProc.Dispose(); _comprProc = null; } if (_ioStream != null) { _ioStream.Close(); _ioStream = null; } if (_pingReceived != null) { _pingReceived.Dispose(); _pingReceived = null; } if (_settingsAckReceived != null) { _settingsAckReceived.Dispose(); _settingsAckReceived = null; } if (OnSessionDisposed != null) { OnSessionDisposed(this, null); } OnSessionDisposed = null; Http2Logger.LogDebug("Session closed"); }
private void Close(ResetStatusCode status) { if (_disposed) return; Http2Logger.LogDebug("Session closing"); _disposed = true; // Dispose of all streams foreach (var stream in StreamDictionary.Values) { //Cancel all opened streams stream.Close(ResetStatusCode.None); } if (!_goAwayReceived) { WriteGoAway(status); //TODO fix delay. wait for goAway send and then dispose WriteQueue //Wait for GoAway send using (var goAwayDelay = new ManualResetEvent(false)) { goAwayDelay.WaitOne(500); } } OnSettingsSent = null; OnFrameReceived = null; if (_frameReader != null) { _frameReader.Dispose(); _frameReader = null; } if (_writeQueue != null) { _writeQueue.Flush(); _writeQueue.Dispose(); } if (_comprProc != null) { _comprProc.Dispose(); _comprProc = null; } if (_ioStream != null) { _ioStream.Close(); _ioStream = null; } if (_pingReceived != null) { _pingReceived.Dispose(); _pingReceived = null; } if (_settingsAckReceived != null) { _settingsAckReceived.Dispose(); _settingsAckReceived = null; } if (OnSessionDisposed != null) { OnSessionDisposed(this, null); } OnSessionDisposed = null; Http2Logger.LogDebug("Session closed"); }