Server/FormMain.cs
changeset 270 5dcd226539d4
parent 269 8e32e51a2edd
child 271 24aec939b286
     1.1 --- a/Server/FormMain.cs	Wed Sep 28 22:31:27 2016 +0200
     1.2 +++ b/Server/FormMain.cs	Wed Oct 05 15:02:09 2016 +0200
     1.3 @@ -1033,7 +1033,12 @@
     1.4  
     1.5          }
     1.6  
     1.7 -        //This is our timer tick responsible to perform our render
     1.8 +        /// <summary>
     1.9 +        /// This is our timer tick responsible to perform our render
    1.10 +        /// TODO: Use a threading timer instead of a Windows form timer.
    1.11 +        /// </summary>
    1.12 +        /// <param name="sender"></param>
    1.13 +        /// <param name="e"></param>
    1.14          private void timer_Tick(object sender, EventArgs e)
    1.15          {
    1.16              //Update our animations
    1.17 @@ -1095,7 +1100,7 @@
    1.18  
    1.19              //Compute instant FPS
    1.20              toolStripStatusLabelFps.Text = (1.0/NewTickTime.Subtract(LastTickTime).TotalSeconds).ToString("F0") + " / " +
    1.21 -                                           (1000/timer.Interval).ToString() + " FPS";
    1.22 +                                           (1000/iTimerDisplay.Interval).ToString() + " FPS";
    1.23  
    1.24              LastTickTime = NewTickTime;
    1.25  
    1.26 @@ -1257,7 +1262,7 @@
    1.27              maskedTextBoxMinFontSize.Text = cds.MinFontSize.ToString();
    1.28              maskedTextBoxScrollingSpeed.Text = cds.ScrollingSpeedInPixelsPerSecond.ToString();
    1.29              comboBoxDisplayType.SelectedIndex = cds.DisplayType;
    1.30 -            timer.Interval = cds.TimerInterval;
    1.31 +            iTimerDisplay.Interval = cds.TimerInterval;
    1.32              maskedTextBoxTimerInterval.Text = cds.TimerInterval.ToString();
    1.33              textBoxScrollLoopSeparator.Text = cds.Separator;
    1.34              //
    1.35 @@ -1563,27 +1568,27 @@
    1.36          private void StartTimer()
    1.37          {
    1.38              LastTickTime = DateTime.Now; //Reset timer to prevent jump
    1.39 -            timer.Enabled = true;
    1.40 +            iTimerDisplay.Enabled = true;
    1.41              UpdateSuspendButton();
    1.42          }
    1.43  
    1.44          private void StopTimer()
    1.45          {
    1.46              LastTickTime = DateTime.Now; //Reset timer to prevent jump
    1.47 -            timer.Enabled = false;
    1.48 +            iTimerDisplay.Enabled = false;
    1.49              UpdateSuspendButton();
    1.50          }
    1.51  
    1.52          private void ToggleTimer()
    1.53          {
    1.54              LastTickTime = DateTime.Now; //Reset timer to prevent jump
    1.55 -            timer.Enabled = !timer.Enabled;
    1.56 +            iTimerDisplay.Enabled = !iTimerDisplay.Enabled;
    1.57              UpdateSuspendButton();
    1.58          }
    1.59  
    1.60          private void UpdateSuspendButton()
    1.61          {
    1.62 -            if (!timer.Enabled)
    1.63 +            if (!iTimerDisplay.Enabled)
    1.64              {
    1.65                  buttonSuspend.Text = "Run";
    1.66              }
    1.67 @@ -2301,8 +2306,8 @@
    1.68  
    1.69                  if (interval > 0)
    1.70                  {
    1.71 -                    timer.Interval = interval;
    1.72 -                    cds.TimerInterval = timer.Interval;
    1.73 +                    iTimerDisplay.Interval = interval;
    1.74 +                    cds.TimerInterval = iTimerDisplay.Interval;
    1.75                      Properties.Settings.Default.Save();
    1.76                  }
    1.77              }
    1.78 @@ -3062,6 +3067,11 @@
    1.79  #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
    1.80          }
    1.81  
    1.82 +
    1.83 +
    1.84 +        int iHarmonyReconnectTries = 0;
    1.85 +        const int KHarmonyMaxReconnectTries = 10;
    1.86 +
    1.87          /// <summary>
    1.88          /// 
    1.89          /// </summary>
    1.90 @@ -3073,9 +3083,12 @@
    1.91                  await Program.HarmonyClient.CloseAsync();
    1.92              }
    1.93  
    1.94 +            bool success = false;
    1.95 +
    1.96              //Reset Harmony client & config
    1.97              Program.HarmonyClient = null;
    1.98              Program.HarmonyConfig = null;
    1.99 +            iTreeViewHarmony.Nodes.Clear();
   1.100  
   1.101              Trace.WriteLine("Harmony: Connecting... ");
   1.102              //First create our client and login
   1.103 @@ -3087,13 +3100,17 @@
   1.104              if (!string.IsNullOrEmpty(authToken) && !aForceAuth)
   1.105              {
   1.106                  Trace.WriteLine("Harmony: Reusing token: {0}", authToken);
   1.107 -                await Program.HarmonyClient.TryOpenAsync(authToken);
   1.108 +                success = await Program.HarmonyClient.TryOpenAsync(authToken);
   1.109              }
   1.110  
   1.111 -            if (!Program.HarmonyClient.IsReady)
   1.112 +            if (!Program.HarmonyClient.IsReady || !success 
   1.113 +                // Only first failure triggers new Harmony server AUTH
   1.114 +                // That's to avoid calling upon Logitech servers too often
   1.115 +                && iHarmonyReconnectTries == 0 )
   1.116              {
   1.117                  //We failed to connect using our token
   1.118                  //Delete it then
   1.119 +                Trace.WriteLine("Harmony: Reseting authentication token!");
   1.120                  Properties.Settings.Default.LogitechAuthToken = "";
   1.121                  Properties.Settings.Default.Save();
   1.122  
   1.123 @@ -3105,18 +3122,65 @@
   1.124                  }
   1.125  
   1.126                  Trace.WriteLine("Harmony: Authenticating with Logitech servers...");
   1.127 -                await Program.HarmonyClient.TryOpenAsync(iTextBoxLogitechUserName.Text, iTextBoxLogitechPassword.Text);
   1.128 +                success = await Program.HarmonyClient.TryOpenAsync(iTextBoxLogitechUserName.Text, iTextBoxLogitechPassword.Text);
   1.129                  //Persist our authentication token in our setting
   1.130 -                Properties.Settings.Default.LogitechAuthToken = Program.HarmonyClient.Token;
   1.131 -                Properties.Settings.Default.Save();
   1.132 +                if (success)
   1.133 +                {
   1.134 +                    Trace.WriteLine("Harmony: Saving authentication token.");
   1.135 +                    Properties.Settings.Default.LogitechAuthToken = Program.HarmonyClient.Token;
   1.136 +                    Properties.Settings.Default.Save();
   1.137 +                }
   1.138              }
   1.139 -
   1.140 -            //Fetch our config
   1.141 -            Program.HarmonyConfig = await Program.HarmonyClient.GetConfigAsync();
   1.142 -            PopulateTreeViewHarmony(Program.HarmonyConfig);
   1.143 -
   1.144 -            //Make sure harmony command actions are showing device name instead of device id
   1.145 -            PopulateTreeViewEvents(CurrentEarObject());
   1.146 +           
   1.147 +            // I've seen this failing with "Policy lookup failed on server".
   1.148 +            Program.HarmonyConfig = await Program.HarmonyClient.TryGetConfigAsync();
   1.149 +            if (Program.HarmonyConfig == null)
   1.150 +            {
   1.151 +                success = false;
   1.152 +            }
   1.153 +            else
   1.154 +            {
   1.155 +                // So we now have our Harmony Configuration
   1.156 +                PopulateTreeViewHarmony(Program.HarmonyConfig);
   1.157 +                // Make sure harmony command actions are showing device name instead of device id
   1.158 +                PopulateTreeViewEvents(CurrentEarObject());
   1.159 +            }
   1.160 +
   1.161 +            // TODO: Consider putting the retry logic one level higher in ResetHarmonyAsync
   1.162 +            if (!success)
   1.163 +            {
   1.164 +                // See if we need to keep trying 
   1.165 +                if (iHarmonyReconnectTries < KHarmonyMaxReconnectTries)
   1.166 +                {
   1.167 +                    iHarmonyReconnectTries++;
   1.168 +                    Trace.WriteLine("Harmony: Failed to connect, try again: " + iHarmonyReconnectTries);
   1.169 +                    await ConnectHarmonyAsync();
   1.170 +                }
   1.171 +                else
   1.172 +                {
   1.173 +                    Trace.WriteLine("Harmony: Failed to connect, giving up!");
   1.174 +                    iHarmonyReconnectTries = 0;
   1.175 +                    // TODO: Could use a data member as timer rather than a new instance.
   1.176 +                    // Try that again in 5 minutes then.
   1.177 +                    // Using Windows Form timer to make sure we run in the UI thread.
   1.178 +                    System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
   1.179 +                    timer.Tick += async delegate (object sender, EventArgs e)
   1.180 +                    {
   1.181 +                        // Stop our timer first as we won't need it anymore
   1.182 +                        (sender as System.Windows.Forms.Timer).Stop();
   1.183 +                        // Then try to connect again
   1.184 +                        await ConnectHarmonyAsync();
   1.185 +                    };
   1.186 +                    timer.Interval = 300000;
   1.187 +                    timer.Start();
   1.188 +                }
   1.189 +            }
   1.190 +            else
   1.191 +            {
   1.192 +                // We are connected with a valid Harmony Configuration
   1.193 +                // Reset our tries counter then    
   1.194 +                iHarmonyReconnectTries = 0;
   1.195 +            }
   1.196          }
   1.197  
   1.198          /// <summary>