コード例 #1
0
            internal void OnPingAckReceived(long payload, Http2Connection connection)
            {
                if (_state != State.PingSent && _state != State.TerminatingMayReceivePingAck)
                {
                    if (NetEventSource.Log.IsEnabled())
                    {
                        connection.Trace($"[FlowControl] Unexpected PING ACK in state {_state}");
                    }
                    ThrowProtocolError();
                }

                if (_state == State.TerminatingMayReceivePingAck)
                {
                    _state = State.Disabled;
                    return;
                }

                // RTT PINGs always carry negative payload, positive values indicate a response to KeepAlive PING.
                Debug.Assert(payload < 0);

                if (_pingCounter != payload)
                {
                    if (NetEventSource.Log.IsEnabled())
                    {
                        connection.Trace($"[FlowControl] Unexpected RTT PING ACK payload {payload}, should be {_pingCounter}.");
                    }
                    ThrowProtocolError();
                }

                RefreshRtt(connection);
                _state = State.Waiting;
            }
コード例 #2
0
            internal void OnDataOrHeadersReceived(Http2Connection connection)
            {
                if (_state != State.Waiting)
                {
                    return;
                }

                long now     = Stopwatch.GetTimestamp();
                bool initial = _initialBurst > 0;

                if (initial || now - _pingSentTimestamp > PingIntervalInTicks)
                {
                    if (initial)
                    {
                        _initialBurst--;
                    }

                    // Send a PING
                    _pingCounter--;
                    if (NetEventSource.Log.IsEnabled())
                    {
                        connection.Trace($"[FlowControl] Sending RTT PING with payload {_pingCounter}");
                    }
                    connection.LogExceptions(connection.SendPingAsync(_pingCounter, isAck: false));
                    _pingSentTimestamp = now;
                    _state             = State.PingSent;
                }
            }
コード例 #3
0
            private void RefreshRtt(Http2Connection connection)
            {
                long     prevRtt    = _minRtt == 0 ? long.MaxValue : _minRtt;
                TimeSpan currentRtt = Stopwatch.GetElapsedTime(_pingSentTimestamp);
                long     minRtt     = Math.Min(prevRtt, currentRtt.Ticks);

                Interlocked.Exchange(ref _minRtt, minRtt); // MinRtt is being queried from another thread

                if (NetEventSource.Log.IsEnabled())
                {
                    connection.Trace($"[FlowControl] Updated MinRtt: {MinRtt.TotalMilliseconds} ms");
                }
            }