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;