У меня есть прототип, который хорошо работает с SSE и WebSockets, но аварий при использовании LongPolling в тот момент, когда я положил немного стресса в браузере.SignalR LongPolling падает с небольшим количеством стресса
Мое приложение может создавать игры, и каждая игра генерирует свои собственные события, и эти события должны быть отправлены в браузер. У меня есть кнопка для создания одной, десяти и сотен игр одновременно. Для создания каждой игры требуется POST-вызов WebAPI, поэтому кнопка 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.
Я не имею ни малейшего понятия о том, что может быть проблема. Есть идеи?
Cheers.
UPDATE:
Я создал небольшой проект, который воспроизводит проблему. Он поделился ею 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");
}
Как выглядит трассировка сети (или скрипач) при использовании longpolling? Эта ошибка может быть связана с https://github.com/SignalR/SignalR/issues/2456 – davidfowl
Правильно, несмотря на то, что я не использую хабы, она выглядит точно так же. Соединения отображаются некоторое время, а затем не работают. Итак, исправление будет в 2.1.0? – vtortola
TBD. Одно из решений может заключаться в том, чтобы не дожидаться, когда группы будут отброшены. Просто вызовите Groups.Add без ожидания. – davidfowl