2017-07-30 113 views
0

我想提高客戶端對signalR客戶端實現的恢復能力。重新連接已斷開連接的SignalR客戶端(JS)的最佳實踐

目前,我這樣做:

hub.server.sendClientNotification(string, appSettings.username()); 

但是偶爾,涉及到連接異常被拋出,因爲無論是在服務器沒有響應,或者客戶端的互聯網連接已經成爲不可用。

我想通過排隊的請求,然後做這樣的事情來解決這個問題:

try { 
    // pop from queue 
    hub.server.sendClientNotification(string, appSettings.username()); 
    // success - discard element 
} catch (e) { 
    // requeue element 
} 

有了這種實現的,我會需要重新初始化使用斷開之間$.connection.hub.start我signalR連接,或者我可以在一段時間內繼續嘗試集線器傳輸嗎?

這是我提議:

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 && 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; 

回答

1

按照documentation

在您可能要自動重新建立連接,它已經丟失後,一些應用程序,並重新連接有企圖時間到。爲此,您可以從您的Closed事件處理程序(JavaScript客戶端上的斷開事件處理程序)調用Start方法。您可能需要等待一段時間才能調用開始,以避免在服務器或物理連接不可用時頻繁執行此操作。以下代碼示例適用於使用生成的代理的JavaScript客戶端。

$.connection.hub.disconnected(function() { 
    setTimeout(function() { 
     $.connection.hub.start(); 
    }, 5000); // Restart connection after 5 seconds. 
});