예제 #1
0
 private void ParseLine(string json)
 {
     // reset error count and backoff flag
     _hardErrorCount = 0;
     _backoffMode    = BackoffMode.None;
     _stateUpdater.UpdateState();
     ConnectionState = UserStreamsConnectionState.Connected;
     UserStreamParser.ParseStreamLine(json, _handler);
 }
예제 #2
0
 public UserStreamReceiver(ApiAccessor accessor, IStreamHandler handler)
 {
     _accessor = accessor;
     _handler = handler;
     ChangeState(StreamState.Disconnected);
     // set default values to parameters
     StallWarnings = true;
     StreamFilterLevel = StreamFilterLevel.None;
     _currentState = StreamState.Connected;
     _backoffMode = BackoffMode.None;
     _backoffWait = 0;
     _hardErrorCount = 0;
 }
예제 #3
0
        private async Task <bool> HandleException(Exception ex)
        {
            Log("Exception on User Stream Receiver: " + Environment.NewLine + ex);
            var tx = ex as TwitterApiException;

            if (tx != null)
            {
                // protocol error
                Log($"Twitter API Exception: [status-code: {tx.StatusCode} twitter-code: {tx.TwitterErrorCode}]");
                _stateUpdater.UpdateState(_account.UnreliableScreenName +
                                          ReceivingResources.UserStreamDisconnectedFormat.SafeFormat(
                                              (int)tx.StatusCode, tx.TwitterErrorCode));
                _handler.OnMessage(new StreamErrorMessage(_account, tx.StatusCode, tx.TwitterErrorCode));
                switch (tx.StatusCode)
                {
                case HttpStatusCode.Unauthorized:
                    Log("Authorization failed.");
                    if (_hardErrorCount > MaxHardErrorCount)
                    {
                        return(false);
                    }
                    break;

                case HttpStatusCode.Forbidden:
                case HttpStatusCode.NotFound:
                    Log("Endpoint not found / not accessible.");
                    if (_hardErrorCount > MaxHardErrorCount)
                    {
                        return(false);
                    }
                    break;

                case HttpStatusCode.NotAcceptable:
                case HttpStatusCode.RequestEntityTooLarge:
                    Log("Specified argument could not be accepted.");
                    return(false);

                case HttpStatusCode.RequestedRangeNotSatisfiable:
                    Log("Permission denied / Parameter out of range");
                    return(false);

                case (HttpStatusCode)420:     // Too many connections
                    Log("Too many connections are established.");
                    return(false);
                }
                // general protocol error
                if (_backoffMode == BackoffMode.ProtocolError)
                {
                    // exponential backoff
                    _backoffWait *= 2;
                }
                else
                {
                    _backoffWait = ProtocolErrorInitialWait;
                    _backoffMode = BackoffMode.ProtocolError;
                }
                if (_backoffWait >= ProtocolErrorMaxWait)
                {
                    Log("Protocol backoff limit exceeded.");
                    _stateUpdater.UpdateState(_account.UnreliableScreenName + ": " +
                                              ReceivingResources.ConnectFailedByProtocol);
                    return(false);
                }
            }
            else
            {
                // network error
                if (_backoffMode == BackoffMode.NetworkError)
                {
                    // linear backoff
                    _backoffWait += NetworkErrorInitialWait;
                }
                else
                {
                    _backoffWait = NetworkErrorInitialWait;
                    _backoffMode = BackoffMode.NetworkError;
                }
                if (_backoffWait >= NetworkErrorMaxWait)
                {
                    Log("Network backoff limit exceeded.");
                    _stateUpdater.UpdateState(_account.UnreliableScreenName + ": " +
                                              ReceivingResources.ConnectFailedByNetwork);
                    return(false);
                }
            }
            Log($"Waiting reconnection... [{_backoffWait} ms]");
            _stateUpdater.UpdateState(_account.UnreliableScreenName + ": " +
                                      ReceivingResources.ReconnectingFormat.SafeFormat(_backoffWait));
            _handler.OnMessage(new StreamWaitMessage(_account, _backoffWait));
            await Task.Delay(TimeSpan.FromMilliseconds(_backoffWait)).ConfigureAwait(false);

            return(true);
        }
예제 #4
0
 private async Task<bool> HandleException(Exception ex)
 {
     Log("Exception on User Stream Receiver: " + Environment.NewLine + ex);
     var tx = ex as TwitterApiException;
     if (tx != null)
     {
         // protocol error
         Log($"Twitter API Exception: [status-code: {tx.StatusCode} twitter-code: {tx.TwitterErrorCode}]");
         _handler.OnMessage(new StreamErrorMessage(_accessor, tx.StatusCode, tx.TwitterErrorCode));
         switch (tx.StatusCode)
         {
             case HttpStatusCode.Unauthorized:
                 Log("Authorization failed.");
                 if (_hardErrorCount > MaxHardErrorCount)
                 {
                     return false;
                 }
                 break;
             case HttpStatusCode.Forbidden:
             case HttpStatusCode.NotFound:
                 Log("Endpoint not found / not accessible.");
                 if (_hardErrorCount > MaxHardErrorCount)
                 {
                     return false;
                 }
                 break;
             case HttpStatusCode.NotAcceptable:
             case HttpStatusCode.RequestEntityTooLarge:
                 Log("Specified argument could not be accepted.");
                 return false;
             case HttpStatusCode.RequestedRangeNotSatisfiable:
                 Log("Permission denied / Parameter out of range");
                 return false;
             case (HttpStatusCode)420: // Too many connections
                 Log("Too many connections are established.");
                 return false;
         }
         // general protocol error
         if (_backoffMode == BackoffMode.ProtocolError)
         {
             // exponential backoff
             _backoffWait *= 2;
         }
         else
         {
             _backoffWait = ProtocolErrorInitialWait;
             _backoffMode = BackoffMode.ProtocolError;
         }
         if (_backoffWait >= ProtocolErrorMaxWait)
         {
             Log("Protocol backoff limit exceeded.");
             return false;
         }
     }
     else
     {
         // network error
         if (_backoffMode == BackoffMode.NetworkError)
         {
             // linear backoff
             _backoffWait += NetworkErrorInitialWait;
         }
         else
         {
             _backoffWait = NetworkErrorInitialWait;
             _backoffMode = BackoffMode.NetworkError;
         }
         if (_backoffWait >= NetworkErrorMaxWait)
         {
             Log("Network backoff limit exceeded.");
             return false;
         }
     }
     Log($"Waiting reconnection... [{_backoffWait} ms]");
     _handler.OnMessage(new StreamWaitMessage(_accessor, _backoffWait));
     await Task.Delay(TimeSpan.FromMilliseconds(_backoffWait)).ConfigureAwait(false);
     return true;
 }
예제 #5
0
 private void ParseLine(string json)
 {
     // reset error count and backoff flag
     _hardErrorCount = 0;
     _backoffMode = BackoffMode.None;
     ChangeState(StreamState.Connected);
     UserStreamParser.ParseStreamLine(json, _handler);
 }