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); }
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; }
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); }
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; }
private void ParseLine(string json) { // reset error count and backoff flag _hardErrorCount = 0; _backoffMode = BackoffMode.None; ChangeState(StreamState.Connected); UserStreamParser.ParseStreamLine(json, _handler); }