2016-01-14 5 views
0

У меня есть концентратор SignalR и два клиента (Windows и PCL для Android и iOS). Ни один из клиентов не может вызвать некоторые методы на сервере. Такое поведение довольно странно, так как методы выглядят очень похожими. Более того, мой коллега может вызывать методы, которые я не могу вызвать, и наоборот, не вызывает методы, которые я вызываю без проблем.Метод SignalR Hub не называется

Вот пример метода, который работает для меня, и не работает для моего коллеги:

public override async Task<bool> RefreshArray(User user, int waitMilis) 
    { 
     var cts = new CancellationTokenSource(); 

     try 
     { 
      cts.CancelAfter(waitMilis); 
      await Proxy.Invoke("RefreshArray", user); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      OnExceptionOccured(ex); 
      return false; 
     } 
    } 

И метод, который не работает для меня, но работает для моего коллеги:

public override async Task<bool> RequestInformation(User user, Product product, int waitMilis) 
    { 
     var cts = new CancellationTokenSource(); 

     try 
     { 
      cts.CancelAfter(waitMilis); 
      await Proxy.Invoke("RequestInformation", user, product); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      OnExceptionOccured(ex); 
      return false; 
     } 
    } 

Да, у меня и у моего коллеги есть точно такой же код. И нет, нет опечаток или разных аргументов. Я попытался получить как можно больше данных из клиентского соединения, установив _connection.TraceLevel = TraceLevels.All; Однако я не получил никакой информации о вызываемых методах, как раз на ответах от концентратора. При вызове RefreshArray я получил именно те данные, которые я запросил. При вызове RequestInformation отладчик никогда даже не ударил точку останова в методе хаба, а параметр _connection.Trace отображался только так: 11:22:45.6169660 - 7bc57897-489b-49a2-8459-3fcdb8fcf974 - SSE: OnMessage(Data: {})

Неужели кто-то решил аналогичную проблему? Есть ли решение?

UPDATE 1

Я просто понял, что я столкнулся с почти такой же вопрос около года назад (Possible SignalR bug in Xamarin Android). StackOverflow также указал мне на вопрос с почти той же проблемой (SignalR on Xamarin.iOS - randomly not able to call Hub method), только что связанный с iOS и Azure. Тем не менее, у меня такая же проблема даже за пределами Xamarin, на Windows Phone 8.1 и Windows 10 Universal App. Более того, я запускаю сервер только локально, так что это не проблема Azure. Действительно ли возможно, что у 2-летней ошибки нет решения?

UPDATE 2

Я только что создал простое консольное приложение с SignalR.Client. В консольном приложении каждый метод работал отлично. Удивительно, но и универсальное приложение Windows 10 начало себя вести должным образом - каждый метод хаба был вызван правильно. Windows Phone 8.1 также улучшил свое поведение (все вызванные методы хаба). Однако время от времени соединение пыталось повторно подключиться (без видимых причин), что привело к ошибке Connection started reconnecting before invocation result was received.. Приложение Android по-прежнему вел себя как раньше.

Итак, я попытался выполнить повторную копию предыдущих шагов и создал другое консольное приложение, но на этот раз с библиотекой SignalR.Client.Portable. К моему разочарованию, никаких изменений в поведении приложений Android не произошло.

На следующей неделе мы начнем тестировать наше приложение на iOS, поэтому я действительно задаюсь вопросом, какие новые странности мы встретим.

ответ

0

Мне удалось решить проблему (по крайней мере, так кажется). Как выяснилось, есть некоторые странные вещи вокруг, когда приложение получает ответ от концентратора SignalR. Кажется, что HubProxy был заблокирован на определенный период времени на Android, в то время как он отключает соединение и начинает периодически подключаться к Windows Phone, не дожидаясь, когда из хаба появится asnwer.

Реализация RefreshArray на ступице было что-то вроде этого:

public async Task RefreshArray(User user) 
{ 
    await Clients.Caller.SendArray(_globalArray); 
    await Clients.Caller.SendMoreInformation(_additionalInfo); 
} 

Поскольку метод послал два метода в качестве ответа, клиент Proxy застрял и каждая платформа справилась с ней по-своему неожиданным образом. Причина, по которой некоторые методы вызывались на моем компьютере, а не на коллегах, была просто потому, что у нас было другое положение точек останова, что позволило приложению разрешить хотя бы некоторые запросы и ответы.

Конечным решением было добавить некоторую синхронизацию в вызов методов. Теперь мой концентратор звонит только await Clients.Caller.SendArray(_globalArray);. Затем это обрабатывается клиентом с событием ArraySent(string[] array), которое затем вызывает метод SendMoreInformation() на концентраторе.

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