SignalR LongPolling crashes with a little of stres

2019-09-01 07:54发布

问题:

I have a prototype that works well with SSE and WebSockets, but crashes when using LongPolling in the moment that I put a little bit of stress in the browser.

My app can create games, and each game generate its own events, and those events must be sent to the browser. I have a button to create one, ten and a hundred games at once. Create each game requires a POST call to a WebAPI, so the x10 button creates 10 requests and x100 creates 100 requests to the server.

When I use SSE or WS, it works nicely, I can call the x100 button and create a hundred games, all the games gets its respective events. I can see the 100 HTTP POST request being all successful.

But if I switch to LongPolling mode, I can create games one by one, as long I do not click too fast, and it works well. In the moment I click fast or click the "ten" or "hundred" button, all WebAPI calls but one get stuck and eventually fails with this message:

{"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()"}

Even running in debug, I cannot see that exception happening anywhere.

And SignalR disconnects:

[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. 

And it is true, the server actually sends a D:1 in the last response, but I don't know why is that happening, I have nothing in my code that disconnects SignalR connections.

It happens in, at least, Google Chrome and IE 10.

I have no clue about what could be the problem. Any idea?

Cheers.

UPDATE:

I have created a small project that reproduces the issue. It have shared it here.

Accessing: http://localhost/LongPollingLoadTest/ we can add one game, ten or a hundred without problems, because it will use SSE or WebSockets if available.

Now, open http://localhost/LongPollingLoadTest/?transport=longPolling. You will see how most of calls gets stuck and also most of the times, the SignalR connection crashes.

I think the problem is somehow related with the groups management:

    [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");
    }

回答1:

In your case looks like the longPolling connection became not alive over DisconnectTimeout (which default value is 30 seconds), then server sent disconnect command to client.

Could you also add SignalR trace in your repro?



回答2:

Issue already reported here as @dfowler indicated: https://github.com/SignalR/SignalR/issues/2456

Cheers.