【问题标题】:SignalR: Wait for connection to be re-established before invoking methodsSignalR:在调用方法之前等待重新建立连接
【发布时间】:2016-05-04 01:30:15
【问题描述】:

我有一个带有许多客户端触发方法的 HubProxy,如下所述:

proxy.invoke('hub_Subscribe');
proxy.invoke('triggerOnServer');
proxy.invoke('dataToServer',someModel);

现在,如果信号器连接到服务器并且我尝试调用上述任何方法,它会给我Connection must be started before data can be sent.Connection was disconnected before invocation result was received. 错误。

我知道可以使用connection.stateChanged 来确认signalR 是否已连接并相应地调用方法。但是需要记录这些事件,以便在信号器连接建立后可以调用它们。

那么,如果连接断开,有没有一种简单的方法来记录这些方法?稍后一旦 signalR 连接启动并运行,调用这些方法?

类似proxy.invoke('dataToServer',someModel).WaitForSignalRToBeConnected();

注意:客户端断开连接后,我使用THIS继续连接到服务器

【问题讨论】:

  • SignalR 客户端中没有像WaitForSignalRToBeConnected 这样的东西。我认为您将需要自己维护一个消息队列。
  • 我希望 SignalR 团队考虑将其用于第 3 版

标签: javascript asp.net signalr


【解决方案1】:

您需要的是使用$q 服务的承诺。

我假设您必须先初始化集线器连接,然后按此顺序调用所有其他三个方法。

如果您还没有用于管理与 signalR 服务器的通信的服务,请创建一个服务。在其中注入$q 服务和signalR。

将以下每个命令包装在单独的方法中:

function doInitialize() {
    ... // connect to signalR
    return $q.when(connection.hub.start());
};

function doHubSubscribe() {
    return $q.when(proxy.invoke('hub_Subscribe'));
};

function doTriggerOnServer() {
    return $q.when(proxy.invoke('triggerOnServer'));
};

function doDataToServer() {
    return $q.when(proxy.invoke('dataToServer',someModel));
};

现在,您可以从您的控制器中对服务的方法进行嵌套调用,其中第一个方法需要通过才能让下一个方法运行:

function initSignalR() {
    return service.doInitialize().then(function () {
        return service.doHubSubscribe();
    }).then(function () {
        return service.doTriggerOnServer();
    }).then(function () {
        return service.doDataToServer();
    })
};

编辑:

如果您想为您的调用添加更多处理,您可以使用 jQuery .done().fail() 方法,如下所示:

function sendDataToServer() {
    $q.when(proxy.invoke('dataToServer', someModel))
                    .done(function (result) {
                          deferred.resolve(result);
                          console.log('success!');
                      })
                      .fail(function () {
                          deferred.reject();
                          console.error('Error invoking server!');
                      }));
    return deferred.promise;
};

您可以向.fail() 方法添加更多处理代码,例如添加$timeout 服务来设置重试次数。

希望这会有所帮助。

【讨论】:

  • 没关系。问题专门针对一旦建立连接然后连接变坏会发生什么?在此期间,客户端调用方法。在断开连接期间调用的方法需要以这样的方式处理,即一旦 signalR 连接建立,它们就会被再次调用。
【解决方案2】:

我目前通过以下承诺解决了这个问题:

function GetOpenConnection() {
    return new Promise((resolve, reject) => {
        const msMax = 1000;
        const msInc = 10;

        var ms = 0;

        var idInterval = setInterval(() => {
            if (connection.connectionState == 1) {
                clearInterval(idInterval);
                resolve(connection);
            }
            
            ms += msInc;

            if (ms >= msMax) {
                clearInterval(idInterval);
                reject(connection);
            }
        }, msInc);
    });
}

用法:

console.log('before GetOpenConnection()');
GetOpenConnection().then((connection) => {
    console.log('Connected: ', connection.connectionState);
    // invoke functions here
}).catch((connection) => {
    console.log('Not connected: ', connection.connectionState);
});
console.log('after GetOpenConnection()');

【讨论】:

    猜你喜欢
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多