private void ResetErrorParams() { this._currentBackOffMode = BackOffMode.None; this._currentBackOffWaitCount = 0; this._hardErrorRetryCount = 0; }
private void HandleException(Exception ex) { // log exception Log("EXCEPTION THROWN!"); ex.ToString() .Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries) .ForEach(this.Log); this.CleanupConnection(); var tae = ex as TwitterApiException; if (tae != null) { Log("Twitter API Exception [error: " + (int)tae.StatusCode + " / code: " + tae.TwitterErrorCode + "]"); _stateUpdater.UpdateState(_account.UnreliableScreenName + ": User Streamsが切断されました" + "(エラー: " + (int)tae.StatusCode + ", コード: " + tae.TwitterErrorCode + ")"); switch (tae.StatusCode) { case HttpStatusCode.Unauthorized: // ERR: Unauthorized, invalid OAuth request? Log(">>> Authorization failed."); if (this.CheckHardError()) { Log(">>> Too many failure is detected. Abort."); this.RaiseDisconnectedByError( "ユーザー認証が行えません。", "PCの時刻設定が正しいか確認してください。回復しない場合は、OAuth認証を再度行ってください。"); return; } break; case HttpStatusCode.Forbidden: case HttpStatusCode.NotFound: Log(">>> Endpoint forbidden."); if (this.CheckHardError()) { Log(">>> Too many failure is detected. Abort."); this.RaiseDisconnectedByError( "ユーザーストリーム接続が一時的、または恒久的に利用できなくなっています。", "エンドポイントへの接続時にアクセスが拒否されたか、またはエンドポイントが削除されています。"); return; } break; case HttpStatusCode.NotAcceptable: case HttpStatusCode.RequestEntityTooLarge: Log(">>> Arguments could not be accepted."); this.RaiseDisconnectedByError( "トラックしているキーワードが長すぎるか、不正な可能性があります。", "(トラック中のキーワード:" + this._trackKeywords.JoinString(", ") + ")"); return; case HttpStatusCode.RequestedRangeNotSatisfiable: Log(">>> Permission denied or parameter error."); this.RaiseDisconnectedByError( "ユーザーストリームに接続できません。", "(システム エラー: 416 Range Unacceptable. Elevated permission is required or paramter is out of range.)"); return; case (HttpStatusCode)420: // ERR: Too many connections // (other client is already connected?) Log(">>> Rate limited.(too many connected)"); this.RaiseDisconnectedByError( "ユーザーストリーム接続が制限されています。", "Krileが多重起動していないか確認してください。短時間に何度も接続を試みていた場合は、しばらく待つと再接続できるようになります。"); return; } Log(">>> general protocol error.)"); // else -> backoff if (this._currentBackOffMode == BackOffMode.ProtocolError) { // wait count is raised exponentially. this._currentBackOffWaitCount *= 2; } else { this._currentBackOffWaitCount = 5000; this._currentBackOffMode = BackOffMode.ProtocolError; } // max wait is 320 sec. if (this._currentBackOffWaitCount >= 320000) { Log(">>> Protocol backoff threshold exceeded."); this.RaiseDisconnectedByError( "Twitterが不安定な状態になっています。", "プロトコル エラーにより、ユーザーストリームに既定のリトライ回数内で接続できませんでした。"); _stateUpdater.UpdateState(_account.UnreliableScreenName + ": User Streamsへ接続できませんでした(プロトコル エラー)"); return; } } else { Log(">>> general network error.)"); // network error // -> backoff if (this._currentBackOffMode == BackOffMode.NetworkError) { // wait count is raised linearly. this._currentBackOffMode += 250; } else { // wait starts 250ms this._currentBackOffWaitCount = 250; this._currentBackOffMode = BackOffMode.NetworkError; } // max wait is 16 sec. if (this._currentBackOffWaitCount >= 16000) { Log(">>> Network backoff threshold exceeded."); this.RaiseDisconnectedByError( "Twitterが不安定な状態になっています。", "ネットワーク エラーにより、ユーザーストリームに規定のリトライ回数内で接続できませんでした。"); _stateUpdater.UpdateState(_account.UnreliableScreenName + ": User Streamsへ接続できませんでした(ネットワーク エラー)"); return; } } Log(">>> wait for reconnection... (" + _currentBackOffWaitCount + " ms)"); // parsing error, auto-reconnect _stateUpdater.UpdateState(_account.UnreliableScreenName + ": User Streamsへの再接続を試みています...(" + _currentBackOffWaitCount + " msec 待機しています)"); this._currentConnection.Add( Observable.Timer(TimeSpan.FromMilliseconds(this._currentBackOffWaitCount)) .Subscribe(_ => this.Reconnect())); }
private void HandleException(Exception ex) { // log exception Log("EXCEPTION THROWN!"); ex.ToString() .Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries) .ForEach(this.Log); this.CleanupConnection(); var tae = ex as TwitterApiException; if (tae != null) { Log("Twitter API Exception [error: " + (int)tae.StatusCode + " / code: " + tae.TwitterErrorCode + "]"); _stateUpdater.UpdateState(_account.UnreliableScreenName + ": User Streamsが切断されました" + "(エラー: " + (int)tae.StatusCode + ", コード: " + tae.TwitterErrorCode + ")"); switch (tae.StatusCode) { case HttpStatusCode.Unauthorized: // ERR: Unauthorized, invalid OAuth request? Log(">>> Authorization failed."); if (this.CheckHardError()) { Log(">>> Too many failure is detected. Abort."); this.RaiseDisconnectedByError( "ユーザー認証が行えません。", "PCの時刻設定が正しいか確認してください。回復しない場合は、OAuth認証を再度行ってください。"); return; } break; case HttpStatusCode.Forbidden: case HttpStatusCode.NotFound: Log(">>> Endpoint forbidden."); if (this.CheckHardError()) { Log(">>> Too many failure is detected. Abort."); this.RaiseDisconnectedByError( "ユーザーストリーム接続が一時的、または恒久的に利用できなくなっています。", "エンドポイントへの接続時にアクセスが拒否されたか、またはエンドポイントが削除されています。"); return; } break; case HttpStatusCode.NotAcceptable: case HttpStatusCode.RequestEntityTooLarge: Log(">>> Arguments could not be accepted."); this.RaiseDisconnectedByError( "トラックしているキーワードが長すぎるか、不正な可能性があります。", "(トラック中のキーワード:" + this._trackKeywords.JoinString(", ") + ")"); return; case HttpStatusCode.RequestedRangeNotSatisfiable: Log(">>> Permission denied or parameter error."); this.RaiseDisconnectedByError( "ユーザーストリームに接続できません。", "(システム エラー: 416 Range Unacceptable. Elevated permission is required or paramter is out of range.)"); return; case (HttpStatusCode)420: // ERR: Too many connections // (other client is already connected?) Log(">>> Rate limited.(too many connected)"); this.RaiseDisconnectedByError( "ユーザーストリーム接続が制限されています。", "Krileが多重起動していないか確認してください。短時間に何度も接続を試みていた場合は、しばらく待つと再接続できるようになります。"); return; } Log(">>> general protocol error.)"); // else -> backoff if (this._currentBackOffMode == BackOffMode.ProtocolError) { // wait count is raised exponentially. this._currentBackOffWaitCount *= 2; } else { this._currentBackOffWaitCount = 5000; this._currentBackOffMode = BackOffMode.ProtocolError; } // max wait is 320 sec. if (this._currentBackOffWaitCount >= 320000) { Log(">>> Protocol backoff threshold exceeded."); this.RaiseDisconnectedByError( "Twitterが不安定な状態になっています。", "プロトコル エラーにより、ユーザーストリームに既定のリトライ回数内で接続できませんでした。"); _stateUpdater.UpdateState(_account.UnreliableScreenName + ": User Streamsへ接続できませんでした(プロトコル エラー)"); return; } } else { Log(">>> general network error.)"); // network error // -> backoff if (this._currentBackOffMode == BackOffMode.NetworkError) { // wait count is raised linearly. this._currentBackOffMode += 250; } else { // wait starts 250ms this._currentBackOffWaitCount = 250; this._currentBackOffMode = BackOffMode.NetworkError; } // max wait is 16 sec. if (this._currentBackOffWaitCount >= 16000) { Log(">>> Network backoff threshold exceeded."); this.RaiseDisconnectedByError( "Twitterが不安定な状態になっています。", "ネットワーク エラーにより、ユーザーストリームに規定のリトライ回数内で接続できませんでした。"); _stateUpdater.UpdateState(_account.UnreliableScreenName + ": User Streamsへ接続できませんでした(ネットワーク エラー)"); return; } } Log(">>> wait for reconnection... (" + _currentBackOffWaitCount + " ms)"); // parsing error, auto-reconnect _stateUpdater.UpdateState(_account.UnreliableScreenName + ": User Streamsへの再接続を試みています...(" + _currentBackOffWaitCount + " msec 待機しています)"); this._currentConnection.Add( Observable.Timer(TimeSpan.FromMilliseconds(this._currentBackOffWaitCount)) .Subscribe(_ => this.Reconnect())); }
private void HandleException(Exception ex) { // log exception Log("EXCEPTION THROWN!"); ex.ToString() .Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries) .ForEach(this.Log); this.CleanupConnection(); var tae = ex as TwitterApiException; if (tae != null) { Log("Twitter API Exception [error: " + (int)tae.StatusCode + " / code: " + tae.TwitterErrorCode + "]"); _stateUpdater.UpdateState(_account.UnreliableScreenName + ReceivingResources.UserStreamDisconnectedFormat.SafeFormat( (int)tae.StatusCode, tae.TwitterErrorCode)); switch (tae.StatusCode) { case HttpStatusCode.Unauthorized: // ERR: Unauthorized, invalid OAuth request? Log(">>> Authorization failed."); if (this.CheckHardError()) { Log(">>> Too many failure is detected. Abort."); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedAuthError); return; } break; case HttpStatusCode.Forbidden: case HttpStatusCode.NotFound: Log(">>> Endpoint forbidden."); if (this.CheckHardError()) { Log(">>> Too many failure is detected. Abort."); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedEndpointError); return; } break; case HttpStatusCode.NotAcceptable: case HttpStatusCode.RequestEntityTooLarge: Log(">>> Arguments could not be accepted."); this.RaiseDisconnectedByError( ReceivingResources.DisconnectedTrackErrorFormat.SafeFormat( this._trackKeywords.JoinString(", "))); return; case HttpStatusCode.RequestedRangeNotSatisfiable: Log(">>> Permission denied or parameter error."); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedRangeError); return; case (HttpStatusCode)420: // ERR: Too many connections // (other client is already connected?) Log(">>> Rate limited.(too many connected)"); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedLimitError); return; } Log(">>> general protocol error.)"); // else -> backoff if (this._currentBackOffMode == BackOffMode.ProtocolError) { // wait count is raised exponentially. this._currentBackOffWaitCount *= 2; } else { this._currentBackOffWaitCount = 5000; this._currentBackOffMode = BackOffMode.ProtocolError; } // max wait is 320 sec. if (this._currentBackOffWaitCount >= 320000) { Log(">>> Protocol backoff threshold exceeded."); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedProtocolError); _stateUpdater.UpdateState(_account.UnreliableScreenName + ": " + ReceivingResources.ConnectFailedByProtocol); return; } } else { Log(">>> general network error.)"); // network error // -> backoff if (this._currentBackOffMode == BackOffMode.NetworkError) { // wait count is raised linearly. this._currentBackOffMode += 250; } else { // wait starts 250ms this._currentBackOffWaitCount = 250; this._currentBackOffMode = BackOffMode.NetworkError; } // max wait is 16 sec. if (this._currentBackOffWaitCount >= 16000) { Log(">>> Network backoff threshold exceeded."); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedNetworkError); _stateUpdater.UpdateState(_account.UnreliableScreenName + ": " + ReceivingResources.ConnectFailedByNetwork); return; } } Log(">>> wait for reconnection... (" + _currentBackOffWaitCount + " ms)"); // parsing error, auto-reconnect _stateUpdater.UpdateState(_account.UnreliableScreenName + ": " + ReceivingResources.ReconnectingFormat.SafeFormat(_currentBackOffWaitCount)); this._currentConnection.Add( Observable.Timer(TimeSpan.FromMilliseconds(this._currentBackOffWaitCount)) .Subscribe(_ => this.Reconnect())); }
private void HandleException(Exception ex) { // log exception Log("EXCEPTION THROWN!"); ex.ToString() .Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries) .ForEach(this.Log); this.CleanupConnection(); var tae = ex as TwitterApiException; if (tae != null) { Log("Twitter API Exception [error: " + (int)tae.StatusCode + " / code: " + tae.TwitterErrorCode + "]"); _stateUpdater.UpdateState(_account.UnreliableScreenName + ReceivingResources.UserStreamDisconnectedFormat.SafeFormat( (int)tae.StatusCode, tae.TwitterErrorCode)); switch (tae.StatusCode) { case HttpStatusCode.Unauthorized: // ERR: Unauthorized, invalid OAuth request? Log(">>> Authorization failed."); if (this.CheckHardError()) { Log(">>> Too many failure is detected. Abort."); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedAuthError); return; } break; case HttpStatusCode.Forbidden: case HttpStatusCode.NotFound: Log(">>> Endpoint forbidden."); if (this.CheckHardError()) { Log(">>> Too many failure is detected. Abort."); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedEndpointError); return; } break; case HttpStatusCode.NotAcceptable: case HttpStatusCode.RequestEntityTooLarge: Log(">>> Arguments could not be accepted."); this.RaiseDisconnectedByError( ReceivingResources.DisconnectedTrackErrorFormat.SafeFormat( this._trackKeywords.JoinString(", "))); return; case HttpStatusCode.RequestedRangeNotSatisfiable: Log(">>> Permission denied or parameter error."); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedRangeError); return; case (HttpStatusCode)420: // ERR: Too many connections // (other client is already connected?) Log(">>> Rate limited.(too many connected)"); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedLimitError); return; } Log(">>> general protocol error.)"); // else -> backoff if (this._currentBackOffMode == BackOffMode.ProtocolError) { // wait count is raised exponentially. this._currentBackOffWaitCount *= 2; } else { this._currentBackOffWaitCount = 5000; this._currentBackOffMode = BackOffMode.ProtocolError; } // max wait is 320 sec. if (this._currentBackOffWaitCount >= 320000) { Log(">>> Protocol backoff threshold exceeded."); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedProtocolError); _stateUpdater.UpdateState(_account.UnreliableScreenName + ": " + ReceivingResources.ConnectFailedByProtocol); return; } } else { Log(">>> general network error.)"); // network error // -> backoff if (this._currentBackOffMode == BackOffMode.NetworkError) { // wait count is raised linearly. this._currentBackOffMode += 250; } else { // wait starts 250ms this._currentBackOffWaitCount = 250; this._currentBackOffMode = BackOffMode.NetworkError; } // max wait is 16 sec. if (this._currentBackOffWaitCount >= 16000) { Log(">>> Network backoff threshold exceeded."); this.RaiseDisconnectedByError(ReceivingResources.DisconnectedNetworkError); _stateUpdater.UpdateState(_account.UnreliableScreenName + ": " + ReceivingResources.ConnectFailedByNetwork); return; } } Log(">>> wait for reconnection... (" + _currentBackOffWaitCount + " ms)"); // parsing error, auto-reconnect _stateUpdater.UpdateState(_account.UnreliableScreenName + ": " + ReceivingResources.ReconnectingFormat.SafeFormat(_currentBackOffWaitCount)); this._currentConnection.Add( Observable.Timer(TimeSpan.FromMilliseconds(this._currentBackOffWaitCount)) .Subscribe(_ => this.Reconnect())); }
private void ResetErrorParams() { this._currentBackOffMode = BackOffMode.None; this._currentBackOffWaitCount = 0; this._hardErrorRetryCount = 0; }
private IDisposable ConnectCore() { this.CheckDisposed(); this.ConnectionState = UserStreamsConnectionState.Connecting; var con = this.Account.ConnectUserStreams(this._trackKeywords, this.Account.IsReceiveRepliesAll) .Do(_ => { if (this.ConnectionState != UserStreamsConnectionState.Connecting) return; this.ConnectionState = UserStreamsConnectionState.Connected; this._currentBackOffMode = BackOffMode.None; }) .SubscribeWithHandler(new HandleStreams(this), this.HandleException, this.Reconnect); return con; }
private void HandleException(Exception ex) { this.CleanupConnection(); var tae = ex as TwitterApiException; if (tae != null) { switch (tae.StatusCode) { case HttpStatusCode.Unauthorized: // ERR: Unauthorized, invalid OAuth request? if (this.CheckHardError()) { this.RaiseDisconnectedByError( "ユーザー認証が行えません。", "PCの時刻設定が正しいか確認してください。回復しない場合は、OAuth認証を再度行ってください。"); return; } break; case HttpStatusCode.Forbidden: case HttpStatusCode.NotFound: if (this.CheckHardError()) { this.RaiseDisconnectedByError( "ユーザーストリーム接続が一時的、または恒久的に利用できなくなっています。", "エンドポイントへの接続時にアクセスが拒否されたか、またはエンドポイントが削除されています。"); return; } break; case HttpStatusCode.NotAcceptable: case HttpStatusCode.RequestEntityTooLarge: this.RaiseDisconnectedByError( "トラックしているキーワードが長すぎるか、不正な可能性があります。", "(トラック中のキーワード:" + this._trackKeywords.JoinString(", ") + ")"); return; case HttpStatusCode.RequestedRangeNotSatisfiable: this.RaiseDisconnectedByError( "ユーザーストリームに接続できません。", "(システム エラー: 416 Range Unacceptable. Elevated permission is required or paramter is out of range.)"); return; case (HttpStatusCode)420: // ERR: Too many connections // (other client is already connected?) this.RaiseDisconnectedByError( "ユーザーストリーム接続が制限されています。", "Krileが多重起動していないか確認してください。短時間に何度も接続を試みていた場合は、しばらく待つと再接続できるようになります。"); return; } // else -> backoff if (this._currentBackOffMode == BackOffMode.ProtocolError) this._currentBackOffWaitCount += this._currentBackOffWaitCount; // wait count is raised exponentially. else this._currentBackOffWaitCount = 5000; if (this._currentBackOffWaitCount >= 320000) // max wait is 320 sec. { this.RaiseDisconnectedByError( "Twitterが不安定な状態になっています。", "プロトコル エラーにより、ユーザーストリームに既定のリトライ回数内で接続できませんでした。"); return; } } else { // network error // -> backoff if (this._currentBackOffMode == BackOffMode.NetworkError) this._currentBackOffMode += 250; // wait count is raised linearly. else this._currentBackOffWaitCount = 250; // wait starts 250ms if (this._currentBackOffWaitCount >= 16000) // max wait is 16 sec. { this.RaiseDisconnectedByError( "Twitterが不安定な状態になっています。", "ネットワーク エラーにより、ユーザーストリームに規定のリトライ回数内で接続できませんでした。"); return; } } Debug.WriteLine("*** USER STREAMS error ***" + Environment.NewLine + ex); Debug.WriteLine(" -> reconnect."); // parsing error, auto-reconnect this._currentConnection.Add( Observable.Timer(TimeSpan.FromMilliseconds(this._currentBackOffWaitCount)) .Subscribe(_ => this.Reconnect())); }
private IDisposable ConnectCore() { this.CheckDisposed(); this.ConnectionState = UserStreamsConnectionState.Connecting; Debug.WriteLine("*USERSTREAMS* " + _account.UnreliableScreenName + ": Starting connection..."); var con = this.Account.ConnectUserStreams(this._trackKeywords, this.Account.ReceiveRepliesAll, this.Account.ReceiveFollowingsActivity) .Do(_ => { if (this.ConnectionState != UserStreamsConnectionState.Connecting) return; this.ConnectionState = UserStreamsConnectionState.Connected; this._currentBackOffMode = BackOffMode.None; }) .SubscribeWithHandler(new HandleStreams(this), this.HandleException, this.Reconnect); return con; }
/// <summary> /// Connect to user streams.<para /> /// Or, update connected streams. /// </summary> public void Connect() { CheckDisposed(); Disconnect(); _connection = this.AuthInfo.ConnectToUserStreams(trackKeywords) .Do(_ => currentBackOffMode = BackOffMode.None) // initialize back-off .Subscribe( _ => Register(_), ex => HandleException(ex), () => { if (_connection != null) { // make reconnect. Disconnect(); System.Diagnostics.Debug.WriteLine("***Auto reconnect***"); Connect(); } }); RaiseIsConnectedEvent(true); }
private void HandleException(Exception ex) { Disconnect(); var wex = ex as WebException; if (wex != null) { if (wex.Status == WebExceptionStatus.ProtocolError) { var res = wex.Response as HttpWebResponse; if (res != null) { // protocol error switch (res.StatusCode) { case HttpStatusCode.Unauthorized: // ERR: Unauthorized, invalid OAuth request? if (CheckHardError()) { RaiseDisconnectedByError("ユーザー認証が行えません。", "PCの時刻設定が正しいか確認してください。回復しない場合は、OAuth認証を再度行ってください。"); return; } break; case HttpStatusCode.Forbidden: case HttpStatusCode.NotFound: if (CheckHardError()) { RaiseDisconnectedByError("ユーザーストリーム接続が一時的、または恒久的に利用できなくなっています。", "エンドポイントへの接続時にアクセスが拒否されたか、またはエンドポイントが削除されています。"); return; } break; case HttpStatusCode.NotAcceptable: case HttpStatusCode.RequestEntityTooLarge: RaiseDisconnectedByError("トラックしているキーワードが長すぎるか、不正な可能性があります。", "(トラック中のキーワード:" + trackKeywords.JoinString(", ") + ")"); return; case HttpStatusCode.RequestedRangeNotSatisfiable: RaiseDisconnectedByError("ユーザーストリームに接続できません。", "(テクニカル エラー: 416 Range Unacceptable. Elevated permission is required or paramter is out of range.)"); return; case (HttpStatusCode)420: // ERR: Too many connections // (other client is already connected?) if (CheckHardError()) { RaiseDisconnectedByError("ユーザーストリーム接続が制限されています。", "Krileが多重起動していないか確認してください。短時間に何度も接続を試みていた場合は、しばらく待つと再接続できるようになります。"); return; } break; } } // else -> backoff if (currentBackOffMode == BackOffMode.Protocol) currentBackOffWaitCount += currentBackOffWaitCount; // wait count is raised exponentially. else currentBackOffWaitCount = 5000; if (currentBackOffWaitCount >= 320000) // max wait is 320 sec. { RaiseDisconnectedByError("Twitterが不安定な状態になっています。", "プロトコル エラーにより、ユーザーストリームに既定のリトライ回数内で接続できませんでした。"); return; } } else { // network error // -> backoff if (currentBackOffMode == BackOffMode.Network) currentBackOffMode += 250; // wait count is raised linearly. else currentBackOffWaitCount = 250; // wait starts 250ms if (currentBackOffWaitCount >= 16000) // max wait is 16 sec. { RaiseDisconnectedByError("Twitterが不安定な状態になっています。", "ネットワーク エラーにより、ユーザーストリームに規定のリトライ回数内で接続できませんでした。"); return; } } } else { currentBackOffMode = BackOffMode.None; if (currentBackOffWaitCount == 110) { RaiseDisconnectedByError("ユーザーストリーム接続が何らかのエラーの頻発で停止しました。", "Twitterが不安定な状態になっているか、仕様が変更された可能性があります: " + ex.Message); return; } if (currentBackOffWaitCount >= 108 && currentBackOffWaitCount <= 109) { currentBackOffWaitCount++; } else { currentBackOffWaitCount = 108; // wait shortly } } System.Diagnostics.Debug.WriteLine("*** USER STREAMS error ***" + Environment.NewLine + ex); System.Diagnostics.Debug.WriteLine(" -> reconnect."); // parsing error, auto-reconnect Observable.Timer(TimeSpan.FromMilliseconds(currentBackOffWaitCount)) .Subscribe(_ => Connect()); }
/// <summary> /// Connect to user streams. /// <para /> /// Or, update connected streams. /// </summary> public void Connect() { CheckDisposed(); Disconnect(); _connection = AuthInfo.ConnectToUserStreams(_trackKeywords) .Do(_ => _currentBackOffMode = BackOffMode.None) // initialize back-off .Subscribe( Register, HandleException, () => { if (_connection != null) { // make reconnect. Disconnect(); Debug.WriteLine("***Auto reconnect***"); Connect(); } }); RaiseIsConnectedEvent(true); }
private IDisposable ConnectCore() { CheckDisposed(); ConnectionState = UserStreamsConnectionState.Connecting; return AuthInfo.ConnectToUserStreams(_trackKeywords) .Do(_ => { ConnectionState = UserStreamsConnectionState.Connected; _currentBackOffMode = BackOffMode.None; }) .Subscribe( Register, HandleException, Reconnect); }