title: Best Practices for reconnecting a disconnected SignalR client (JS)
body: <p>I'd like to improve the resilience of my clientside implementation of a signalR client.  </p>
  
  <p>Currently, I do this: </p>
  
  <pre><code>hub.server.sendClientNotification(string, appSettings.username());
  </code></pre>
  
  <p>However occasionally, an exception related to connectivity is thrown because either the server is not responding or the client's internet connection has become unusable.  </p>
  
  <p>I'd like to solve this by queuing up requests and then doing something like this:</p>
  
  <pre><code>try {
      // pop from queue
      hub.server.sendClientNotification(string, appSettings.username());
      // success - discard element
  } catch (e) {
      // requeue element
  }
  </code></pre>
  
  <p>With this kind of implementation, would I need to re-initialize my signalR connection using <code>$.connection.hub.start</code> between disconnects, or can I just continue attempting hub transmits within an interval?</p>
  
  <p>This is what I'm proposing: </p>
  
  <pre><code>var hub = null;
  
  const internalQueue = [];
  
  const states = {
      connecting: 0, connected: 1, reconnecting: 2, disconnected: 4
  }
  
  const signalrModule = {};
  
  var isInitialized = false;
  
  const connectSignalR = function () {
      return new Promise(function (resolve, reject) {
          if ($.connection.hub.state == states.connected) {
              resolve();
          } else {
              window.hubReady = $.connection.hub.start({ transport: ["serverSentEvents", "foreverFrame", "longPolling"] });
              window.hubReady.done(function () {
                  isInitialized = true;
                  resolve();
              });
              window.onbeforeunload = function (e) {
                  $.connection.hub.stop();
              };
          }
      })
  }
  
  signalrModule.init = function (handleNotification) {
      hub = $.connection.appHub;
      hub.client.clientNotification = handleNotification;
      $.connection.hub.qs = {
          "username": appSettings.username()
      };
      connectSignalR();
  }
  
  const tryEmptyQueue = function () {
      connectSignalR().then(function() {
          if (isInitialized) {
              var continueTrying = true;
              while (internalQueue.length &amp;&amp; continueTrying) {
                  const nextMessage = internalQueue.shift();
                  try {
                      hub.server.sendClientNotification(nextMessage, appSettings.username());
                  } catch (e) {
                      internalQueue.push(nextMessage);
                      continueTrying = false;
                  }
              }
          }
      })
  }
  
  signalrModule.sendClientNotification = function (message) {
      if (typeof message != "string") {
          message = JSON.stringify(message);
      }
      if (isInitialized) {
          try {
              hub.server.sendClientNotification(message, appSettings.username());
              tryEmptyQueue();
          } catch (e) {
              logger.log("SignalR disconnected; queuing request", logger.logLevels.warning);
              internalQueue.push(message);
          }
      } else {
          internalQueue.push(message);
      };
  }
  
  const internalQueueInterval = setInterval(function () {
      tryEmptyQueue();
  }, 5000);
  
  return signalrModule;
  </code></pre>