10

我使用基于 SignalR (jquery.signalR-2.0.0-beta2.js) 的实时消息传递系统开发了一个 asp.net mvc 应用程序。问题是在 SignalR 连接启动后无法加载所有部分视图。在这种情况下,$.connection.hub.start({ transport: 'longPolling'}).done(function () { applicationHub.server.connectUser(); }) 之后的所有 ajax 请求都处于挂起状态。是否可以使此请求异步或者它是 SignalR 中的错​​误?谢谢你的帮助!

SignalR 调用:

<script type="text/javascript">

    $(document).ajaxStop(function () {
        var applicationHub = $.connection.applicationHub;

        if ($.connection.hub && $.connection.hub.state == $.signalR.connectionState.disconnected) {

            registerConversationClientMethods(applicationHub);

            $.connection.hub.start({ transport: 'longPolling'}).done(function () {
                applicationHub.server.connectUser();
            })
            .fail(function () {

            });
        }
    });
</script>

呈现局部视图的 Ajax 调用:

函数 LoadActivities(id, type, container, action, loaderpath) {

var url = action + '/?id=' + id + '&type=' + type;
var targetDiv = container;
var ajaxLoading = "<img id='ajax-loader' src='" + loaderpath + "' height='6' width='50' style='margin:5px;'>";

$(targetDiv).html("<div align='center'>" + ajaxLoading + "</div>");

$.get(url, null, function (result) {
    $(targetDiv).html(result);
});

}

4

2 回答 2

6

我对可能导致问题的原因有另一种解释。

由于这个问题是在 2013 年提出的,我认为作者已经找到了解决问题的方法。但由于我花了几个小时来挖掘我的,我相信分享我的经验是我的责任。

架构概述: Asp.Net SPA 应用程序在客户端使用 AngularJS,在服务器端使用 WebApi 2.0 和 SignalR 2.1。

问题症状:应用程序启动并正常运行,但一段时间后所有请求(SignalR 和 WebApi)都卡住了。“卡住”是指 WebApi 请求是在客户端发出的,但控制器方法永远不会被调用。第一个被冻结的始终是 SignalR 请求。

网络监视器

经过一番搜索,我发现了这些症状的最可能原因。这是John Culviner在这篇文章中详细描述的“会话状态阻塞”问题。

由于我的应用程序没有使用会话,我只是在应用程序级别将它们切换到只读模式:

protected void Application_Start()
{
    // Some extra initialization here
    Context.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly);
}

这没有帮助。

我继续我的研究,我相信到那时我已经阅读了每篇带有关键字SignalR、连接、卡住、冻结、挂起的文章或错误报告。似乎与我的案子无关。因此,我没有搜索所使用的技术可能存在的问题,而是开始分析我自己的代码可能出现的问题。它就在那里。

我的问题在Shaun 的这篇文章中有很好的描述。这是概述。在标准 MVC 世界中,SignalR 自己管理其连接。当您移动到另一个页面时,它会自动断开连接。因此,您可以只创建连接并忘记它。不幸的是,这不适用于 SPA/AngularJS 应用程序。SignalR 连接永远不会知道 SPA 内的页面已更改,也永远不会断开连接。当您返回该页面时,将创建一个新的 SignalR 连接。在我的观察中,您需要执行大约 10 次才能使服务请求的管道卡住。

因此,您在这里要做的就是为 SignalR 连接创建一个停止函数,并在更改 SPA 中的页面之前手动调用它:

stop: function() {
    if (connection && connection.state && connection.state !== 4 /* disconnected */) {
        connection.stop();
    }
},

在控制器中:

$scope.$on('$destroy', function() {
    clientPushHubProxy.stop();
});
于 2015-02-18T12:15:02.433 回答
1

将@bjornhol 的回答更进一步——所有 SignalR 请求(正在加载更多 AJAX)排队的问题也发生在我身上。我认为这是 jQuery 的问题,但实际上它是会话状态。对于该控制器,如果您可以将 SessionStateBehaviour 设置为 ReadOnly 或 Disabled,您将看到请求同时通过。请也查看此链接http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/希望这会有所帮助。

于 2013-08-09T04:07:26.157 回答