重新连接已断开连接的SignalR客户端(JS)的最佳实践

重新连接已断开连接的SignalR客户端(JS)的最佳实践

问题描述:

我想提高客户端对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; 

按照documentation

在您可能要自动重新建立连接,它已经丢失后,一些应用程序,并重新连接有企图时间到。为此,您可以从您的Closed事件处理程序(JavaScript客户端上的断开事件处理程序)调用Start方法。您可能需要等待一段时间才能调用开始,以避免在服务器或物理连接不可用时频繁执行此操作。以下代码示例适用于使用生成的代理的JavaScript客户端。

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