SignalR 客户端回调方法被多次调用

SignalR client callback method getting called multiple times

我们有一个 SignalR 客户端回调方法,当我们离开并返回到它包含的页面时,它会被调用多次。例如:页面是salesUpdate.html(Angular模板),在这个页面第一次来的时候,回调会在它的事件发生时执行一次。现在,当我们从这个页面移到另一个页面(比如 purchaseUpdate.html),然后回到这个页面,即 salesUpdate.html,这个 SignalR 客户端回调方法将执行两次。它会在我们离开页面并返回页面时执行多次。从服务端,这个方法从ASP.NETWebAPI调用,WebAPI只命中一次,后面所有的回调执行都不会命中WebAPI。 这是客户端回调方法:

var con;
var apiMsgProxy;
$(document).ready(function () {
        con = $.hubConnection('http://localhost:51123/signalr');
        apiMsgProxy = con.createHubProxy('salesHub');

        apiMsgProxy.on('SendSaleUpdate', function (uMsg) {
            console.log("Call back SendSaleUpdate called - " + uMsg);
        });
        con.start().done(function () {
        console.log("SignalR connection opened - " + con.state);
        }).fail(function () { 
            console.log('Could not Connect SignalR hub!'); 
        });
});

任何指向此的指示将不胜感激。

我知道很久以前就有人问过这个问题。但我遇到了同样的问题并找到了解决方案。以为我会和大家分享。在问题中, "salesHub" 被初始化,并且在页面加载时使用集线器的 .on("SendSaleUpdate") 方法添加事件处理程序。显然,如果您不 "turn off" 该处理程序,它将在客户端启动集线器时多次被 SignalR 调用(在同一连接仍处于打开状态时访问同一页面。)为了防止这种情况发生,当用户离开页面时,您需要调用 hub 的 .off("SendSaleUpdate") 方法。这为我解决了同样的问题。

这是一个老问题,但因为我在我的案例中找到了解决方案,所以更新它可能会对某人有所帮助。所以在我的例子中,由于 apiMsgProxy 是一个全局变量,所以每次页面刷新和重新加载时,它都会每次注册 SendSaleUpdate 函数,并且注册的次数与它注册的次数一样多

请不要使用默认的 auto-generated 代理:

var contosoChatHubProxy = $.connection.contosoChatHub;
contosoChatHubProxy.client.addContosoChatMessageToPage = function (name, message) {
    console.log(name + ' ' + message);
};

相反,实例化一个新连接,并在不使用生成的代理的情况下定义您的客户端方法:

var connection = $.hubConnection(`${yourApplicationPath}/signalr`, { useDefaultPath: false });
var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
contosoChatHubProxy.off('addContosoChatMessageToPage').on('addContosoChatMessageToPage', function(name, message) {
    console.log(name + ' ' + message);
});

我在 SignalR 版本 2.2.2 到 2.4.3 中发现了这个错误,使用自动生成的代理,它会调用您的客户端事件处理程序 contosoChatHubProxy.client.addContosoChatMessageToPage 与您调用 $.connection.contosoChatHub.hub.start() 的次数一样多。

我认为在 start() 中,它将重用当前代理,并且错误地,它加倍了附加到客户端事件的事件处理程序:contosoChatHubProxy.client.addContosoChatMessageToPage.

我最终通过实例化代理而不是使用 auto-generated 解决了这个问题。

此致