SignalR Long Polling因一点压力而崩溃

时间:2014-01-14 14:58:41

标签: asp.net-mvc-4 asp.net-web-api signalr long-polling

我有一个适用于SSE和WebSockets 的原型,但是当我在浏览器中施加一些压力时,在使用LongPolling 时会崩溃。< / p>

我的应用可以创建游戏,每个游戏都会生成自己的事件,并且这些事件必须发送到浏览器。我有一个按钮可以同时创建一个,十个和一百个游戏。创建每个游戏需要对WebAPI进行POST调用,因此x10按钮创建10个请求,x100创建100个请求到服务器。

当我使用SSE或WS时,它运行良好,我可以调用x100按钮并创建一百个游戏,所有游戏都会获得各自的事件。我可以看到100 HTTP POST请求都是成功的。

但是如果我切换到LongPolling模式,我可以逐个创建游戏,只要我不点击太快,它就能很好地运行。在我点击快速或单击“十”或“百”按钮的那一刻,所有WebAPI调用但一个卡住并最终因此消息而失败:

  

{"Message":"Anerrorhasoccurred.","ExceptionMessage":"Ataskwascanceled.","ExceptionType":"System.Threading.Tasks.TaskCanceledException","StackTrace":"atSystem.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__1.MoveNext()\r\n---Endofstacktracefrompreviouslocationwhereexceptionwasthrown---\r\natSystem.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\natSystem.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Tasktask)\r\natSystem.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Tasktask)\r\natSystem.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()"}

即使在调试中运行,我也看不到任何地方发生异常。

SignalR断开连接:

[14:24:37 GMT+0000 (GMT Standard Time)] SignalR: Long poll complete. jquery.signalR-2.0.1.js:75
[14:24:37 GMT+0000 (GMT Standard Time)] SignalR: Disconnect command received from server. jquery.signalR-2.0.1.js:75
[14:24:37 GMT+0000 (GMT Standard Time)] SignalR: Stopping connection. 

确实,服务器实际上在最后一个响应中发送了D:1,但我不知道为什么会发生这种情况,我的代码中没有任何内容可以断开SignalR连接。

至少发生在Google Chrome和IE 10上。

我不知道可能是什么问题。有什么想法吗?

干杯。

更新

我创建了一个可以重现问题的小项目。它已经分享了它here

访问:http://localhost/LongPollingLoadTest/我们可以添加一个游戏,十个或一百个没有问题,因为它将使用SSE或WebSockets(如果可用)。

现在,打开http://localhost/LongPollingLoadTest/?transport=longPolling。您将看到大多数呼叫如何被卡住,而且大多数时候,SignalR连接都会崩溃。

我认为问题在某种程度上与群体管理有关:

    [AcceptVerbs("POST")]
    public async Task<GameInfo> Post([FromBody]GameRequest request)
    {
        var game =new GameInfo() { Id = Guid.NewGuid(), Name = request.Name };
        if (_games.TryAdd(game.Id, game))
        {
            var context = GlobalHost.ConnectionManager.GetConnectionContext<MyPersistentConnection>();
            await context.Groups.Add(request.ConnectionId, game.Id.ToString());
            await context.Connection.Broadcast(game);
            Thread.Sleep(100);
            return game;
        }
        else
            throw new ArgumentException("Already exists");
    }

2 个答案:

答案 0 :(得分:0)

在你的情况下,看起来longPolling连接在DisconnectTimeout上没有活动(默认值是30秒),然后服务器发送了disconnect命令给客户端。

你还可以在你的repro中添加SignalR跟踪吗?

答案 1 :(得分:0)

此处已报告的问题为@dfowler表示:https://github.com/SignalR/SignalR/issues/2456

干杯。