【问题标题】:Best Practices for reconnecting a disconnected SignalR client (JS)重新连接断开连接的 SignalR 客户端 (JS) 的最佳实践
【发布时间】:2017-07-30 00:39:25
【问题描述】:

我想提高 signalR 客户端的客户端实现的弹性。

目前,我这样做:

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

但是,有时会抛出与连接相关的异常,因为服务器没有响应或客户端的 Internet 连接变得不可用。

我想通过排队请求然后做这样的事情来解决这个问题:

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;

【问题讨论】:

    标签: signalr signalr.client


    【解决方案1】:

    关注documentation

    在某些应用程序中,您可能希望在连接丢失并且尝试重新连接超时后自动重新建立连接。为此,您可以从 Closed 事件处理程序(JavaScript 客户端上的断开连接事件处理程序)调用 Start 方法。您可能希望在调用 Start 之前等待一段时间,以避免在服务器或物理连接不可用时过于频繁地执行此操作。以下代码示例适用于使用生成代理的 JavaScript 客户端。

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

    【讨论】:

    • 使用这种方法,重新连接的客户端是否会被视为同一个客户端,并且在断开连接时是否会收到发送给它的任何排队消息?
    • 用户将被连接到一个新的 connectionID。就个人而言,我不依赖 connectionID,而是使用组,当他们重新连接时,它们会被添加回自己的组。我不相信会收到排队的消息,至少不是我的经验。如果您存储了要发送的消息并根据查看它们的用户对其进行标记,这是有可能的,但这是另一个话题。
    猜你喜欢
    • 2021-12-05
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    相关资源
    最近更新 更多