2014-01-14 5 views
0

У меня есть прототип, который хорошо работает с 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"); 
    } 
+0

Как выглядит трассировка сети (или скрипач) при использовании longpolling? Эта ошибка может быть связана с https://github.com/SignalR/SignalR/issues/2456 – davidfowl

+0

Правильно, несмотря на то, что я не использую хабы, она выглядит точно так же. Соединения отображаются некоторое время, а затем не работают. Итак, исправление будет в 2.1.0? – vtortola

+0

TBD. Одно из решений может заключаться в том, чтобы не дожидаться, когда группы будут отброшены. Просто вызовите Groups.Add без ожидания. – davidfowl

ответ

0

В вашем случае выглядит как соединение longPolling стал не живым над DisconnectTimeout (значение которого по умолчанию составляет 30 секунд), то сервер послал команду отключения к клиенту.

Не могли бы вы также добавить трассировку SignalR в своем воспроизведении?

+0

Я боюсь, что след не предоставил никакой соответствующей информации. Я создал небольшие проекты, которые воспроизводят эту проблему. – vtortola

+0

Не уверен, что этот поток все еще активен, но когда longpolling - это транспорт, функция DisconnectTimeout/KeepAlive не используется. 110-секундное соединение ConnectionTimeout. – Adam

Смежные вопросы