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");
        }
示例#3
0
        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");
        }