Example #1
0
 public AccountScheduler(AccountInfo info)
 {
     this._accountInfo = info;
     this.AddSchedule(new HomeReceiveTask(info));
     this.AddSchedule(new MentionReceiveTask(info));
     this.AddSchedule(new DirectMessageReceiveTask(info));
     this.AddSchedule(new SentDirectMessageReceiveTask(info));
     this.AddSchedule(new FavoritesReceiveTask(info));
     this.AddSchedule(new MyTweetsTask(info));
     Task.Factory.StartNew(() =>
         {
             try
             {
                 // テストを飛ばす
                 ApiHelper.ExecApi(() => info.Test());
             }
             catch { }
         });
     ThreadHelper.Halt += () => this.StopSchedule();
 }
Example #2
0
        /// <summary>
        /// ストリーミングAPIへ接続します。<para />
        /// 接続に失敗した場合、規定アルゴリズムに沿って自動で再接続を試みます。<para />
        /// それでも失敗する場合はfalseを返します。この場合、再接続を試みてはいけません。
        /// </summary>
        /// <param name="track">トラック対象キーワード</param>
        private void ConnectCore(AccountInfo info, string track)
        {
            try
            {
                int failureWaitSec = 0;
                while (true)
                {
                    // 接続
                    try
                    {
                        using (var n = NotifyStorage.NotifyManually("@" + info.ScreenName + ": インターネットへの接続を確認しています..."))
                        {
                            while (!NetworkInterface.GetIsNetworkAvailable())
                            {
                                info.ConnectionState = ConnectionState.WaitNetwork;
                                ConnectionManager.OnConnectionStateChanged(EventArgs.Empty);
                                // ネットワークが利用可能になるまでポーリング
                                Thread.Sleep(10000);
                            }
                        }

                        using (var n = NotifyStorage.NotifyManually("@" + info.ScreenName + ": 接続のテストをしています..."))
                        {
                            info.ConnectionState = ConnectionState.WaitTwitter;
                            ConnectionManager.OnConnectionStateChanged(EventArgs.Empty);
                            try
                            {
                                if (!ApiHelper.ExecApi(() => info.Test()))
                                    throw new Exception();
                            }
                            catch
                            {
                                throw new WebException("Twitterが応答を停止しています。");
                            }
                        }

                        using (var n = NotifyStorage.NotifyManually("@" + info.ScreenName + ": 接続しています..."))
                        {
                            info.ConnectionState = ConnectionState.TryConnection;
                            ConnectionManager.OnConnectionStateChanged(EventArgs.Empty);
                            System.Diagnostics.Debug.WriteLine("User Streams Connection with Track: " + track);
                            connection = streamingCore.ConnectNew(
                                info, StreamingDescription.ForUserStreams(TwitterDefine.UserStreamsTimeout,
                                track: track, repliesAll: info.AccountProperty.UserStreamsRepliesAll));
                        }
                    }
                    catch (WebException we)
                    {
                        if ((int)we.Status == 420)
                        {
                            // 多重接続されている
                            throw new WebException("@" + info.ScreenName + ": 多重接続されています。接続できません。");
                        }

                        if (we.Status == WebExceptionStatus.Timeout) // タイムアウト例外なら再試行する
                        {
                            NotifyStorage.Notify("@" + info.ScreenName + ": User Streams接続がタイムアウトしました。再試行します...");
                        }
                        else
                        {
                            string descText = we.Status.ToString();
                            if (we.Status == WebExceptionStatus.UnknownError)
                            {
                                descText = we.Message;
                            }
                            if (we.Status == WebExceptionStatus.ProtocolError)
                            {
                                var hwr = we.Response as HttpWebResponse;
                                if (hwr != null)
                                {
                                    descText += " - " + hwr.StatusCode + " : " + hwr.StatusDescription;
                                }
                            }
                            throw new WebException("接続に失敗しました。(" + descText + ")");
                        }
                    }
                    catch
                    {
                        throw;
                    }

                    if (connection != null)
                    {
                        // Connection successful
                        info.ConnectionState = ConnectionState.Connected;
                        ConnectionManager.OnConnectionStateChanged(EventArgs.Empty);
                        return;
                    }

                    if (failureWaitSec > 0)
                    {
                        if (failureWaitSec > Setting.Instance.ConnectionProperty.UserStreamsConnectionFailedMaxWaitSec)
                        {
                            throw new WebException("User Streamsへの接続に失敗しました。");
                        }
                        else
                        {
                            NotifyStorage.Notify("@" + info.ScreenName + ": User Streamsへの接続に失敗。再試行まで" + failureWaitSec.ToString() + "秒待機...", failureWaitSec / 1000);

                            // ウェイトカウント
                            Thread.Sleep(failureWaitSec * 1000);
                            NotifyStorage.Notify("@" + info.ScreenName + ": User Streamsへの接続を再試行します...");
                        }
                    }
                    else
                    {
                        NotifyStorage.Notify("@" + info.ScreenName + ": User Streamsへの接続に失敗しました。再試行します...");
                    }

                    // 最初に失敗したらすぐに再接続
                    // 2回目以降はその倍に増やしていく
                    // 300を超えたら接続失敗で戻る
                    if (failureWaitSec == 0)
                    {
                        failureWaitSec = Setting.Instance.ConnectionProperty.UserStreamsConnectionFailedInitialWaitSec;
                    }
                    else
                    {
                        failureWaitSec *= 2;
                    }
                }
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception e)
            {
                this.AccountInfo.ConnectionState = ConnectionState.Disconnected;
                ConnectionManager.OnConnectionStateChanged(EventArgs.Empty);
                throw new WebException("User Streamsへの接続に失敗しました。", e);
            }
        }