HttpNotificationChannel Open (), выбрасывающий InvalidOperationException («Не удалось открыть канал») - PullRequest
6 голосов
/ 01 марта 2011

Я пишу приложение для Windows Phone 7, которое использует Push-уведомления и имеет класс, отвечающий за управление взаимодействиями между MS Notification Server и моим сервисом в облаке.Однако, когда я пытаюсь открыть канал на моем устройстве, HttpNotificationChannel генерирует исключение InvalidOperationException с сообщением «Не удалось открыть канал».В соответствии с MSDN я должен попытаться снова открыть канал.

Мой фрагмент кода для открытия push-уведомлений соответствует стандартному шаблону:

public class HttpNotification {
  private const string kChannelName = "MyApp.PushNotification";

  private HttpNotificationChannel _Channel;

  public void Register() {
    try {
      _Channel = HttpNotificationChannel.Find(kChannelName);
      if (_Channel == null) {
        _Channel = new HttpNotificationChannel(kChannelName);
        InstallEventHandlers();

        // This line throws
        _Channel.Open();
      } else {
        InstallEventHandlers();
      };
    } catch (InvalidOperationException ex) {
      MessageBox.Show(string.Format("Failed to initialise Push Notifications - {0}", ex.Message));
    };
  }
}

Я не совсем точно понимаю, что означает MSDN, "попробуйте снова открыть канал".Я обернул вызов Open () в try / catch и дремал 5 секунд между попытками, но это не удалось.Я также пытался использовать тот же подход для всего метода (т. Е. Делать вызов HttpNotificationChannel.Find () каждый раз, когда он выбрасывает) безрезультатно.

Я знаю, что это немного неопределенно - ноинтересно, есть ли у кого-нибудь предложения по обработке этого?Этот же код работает безупречно в эмуляторе, но на моем реальном устройстве происходит сбой каждый раз, даже после удаления и повторной установки моего приложения.Учитывая, что это мой настоящий телефон, я немного неохотно делаю аппаратный сброс в надежде, что это решит эту проблему, и не чувствую себя комфортно, выпуская приложение на рынок с этой проблемой, преследующей меня.

Обновление. Дополнительный момент: я использую канал без проверки подлинности, поэтому для моей облачной службы не установлен сертификат.

Обновление № 2. Далее я только что попытался развернуть Microsoft Phone Push Recipe длямое устройство, и оно также выдает то же исключение.

Ответы [ 2 ]

6 голосов
/ 02 марта 2011

Итак, из вашего комментария я понимаю, что он работает на вашем эмуляторе, но не на вашем телефоне, верно?Вы случайно не использовали название канала в другом / предыдущем приложении?

Дело в том, что эмулятор возвращается в состояние по умолчанию каждый раз, когда закрывается, а ваш телефон - нет.Определенное имя канала может использоваться только одним приложением.Таким образом, если имя канала использовалось другим приложением на том же телефоне, прежде чем оно все еще зарегистрировано в этом приложении, и вы не можете получить к нему доступ из своего приложения.

И наоборот, приложение также может регистрировать не более одного канала, поэтому, если с ним уже связано одно имя, вы не сможете зарегистрировать новый, пока не отмените регистрацию старого и не перезагрузите устройство .Также нет способа запросить, какой канал связан с вашим приложением.

В конечном итоге, когда я застрял в этом цикле, я изменил название канала и мои ApplicationID продукта зарегистрировались в WMAppManifest.xml, и он снова заработал для меня

<App xmlns="" ProductID="{d57ef66e-f46c-4b48-ac47-22b1e924184b}"

Обновление Мой компьютер вышел из строя в эти выходные, слава богу, за WHS и резервные копии.В любом случае ниже мой исходный код.Я заметил две отличия.

  1. Сначала я создал метод с именем RepeatAttemptExecuteMethod(), которому я передаю весь исполняемый код в качестве делегата.Число 10, плавающее где-то в конце, - это количество попыток повторения.Если вы повторяете только метод .Open каждые 5 секунд, разница может заключаться в том, что я также снова вызываю методы Find и New ...

  2. Другое отличие, которое я вижу, состоит в том, что мой кодпредполагается, что _appChannel.ChannelUri может быть нулевым.В этом случае он ожидает, когда канал вызовет событие, и затем выполняет работу, связанную с фактическим каналом, находящимся там.Но так как ваш пример кода не выполняет никакой подобной работы, я сомневаюсь, что это будет то, что вы ищете

    protected override void Load(PhoneApplicationPage parent)
    {
        Verkeer.Helper.ExternalResources.RepeatAttemptExecuteMethod(() => 
        {
            _appChannel = HttpNotificationChannel.Find(CHANNELNAME);
            if (_appChannel == null)
            {
                _appChannel = new HttpNotificationChannel(CHANNELNAME);
                SetUpDelegates();
            }
            else
            {
                SetUpDelegates();
                //if (_appChannel.ChannelUri != null) this.NotificationChannel = _appChannel.ChannelUri;
            }
            if (_appChannel.ChannelUri != null) this.NotificationChannel = _appChannel.ChannelUri;
            else
            {
                try
                {
                    _appChannel.Open();
                }
                catch { }
            }
    
            BindToShellTile();
    
            App.ViewModel.TrafficInfo.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(TrafficInfo_PropertyChanged);
    
            if (App.ViewModel.TrafficInfo.TrafficImage != null && this.NotificationChannel != null)
            {
                CreateTiles();
            }
        },10);
    }
    
    private void BindToShellTile()
    {
        if (!_appChannel.IsShellTileBound && App.ViewModel.PanItemSettings.AutomaticallyUpdateTile)
        {
            Collection<Uri> ListOfAllowedDomains = new Collection<Uri> { new Uri("http://m.anwb.nl/") };
            _appChannel.BindToShellTile(ListOfAllowedDomains);
        }
    }
    
    
    void TrafficInfo_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "TrafficImage")
        {
            if (App.ViewModel.PanItemSettings.AutomaticallyUpdateTile && this.NotificationChannel != null)
            {
                CreateTiles();
            }
        }
    }
    
0 голосов
/ 01 марта 2011

@ slaad .. вот несколько вещей, которые я бы проверил, если вы их еще не попробовали:

  1. Ваше фактическое устройство имеет подключение для передачи данных, верно?doh:)
  2. Как вы храните существующий канал в изолированном хранилище?Убедитесь, что функция Find () работает, и что вы не пытаетесь воссоздать канал, который существует, что приводит к исключению.
  3. Проверьте, есть ли у вашего создания канала проблемы с доменным именем или сертификатами. Попробуйте эту ссылку
  4. Сверьте каждый шаг вашего процесса с this

Извините, я не могу вам помочь.

...