HttpNotificationChannel Open()抛出InvalidOperationException("无法打开频道")

MrM*_*son 6 c# push-notification windows-phone-7 mpns

我正在编写一个使用推送通知的Windows Phone 7应用程序,并且有一个类负责管理MS Notification Server与我在云中的服务之间的交互.但是,当我试图在我的设备上打开频道时,HttpNotificationChannel会抛出InvalidOperationException,并显示消息"无法打开频道".根据MSDN, 我应该尝试再次打开频道.

我打开推送通知的代码段遵循标准模式;

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));
    };
  }
}
Run Code Online (Sandbox Code Playgroud)

我不确定MSDN的意思是"尝试再次打开频道".我已经在try/catch中调用了Open(),并在两次尝试之间暂停5秒,但是没有成功.我也尝试了相同的方法围绕整个方法(即每次抛出时调用HttpNotificationChannel.Find())无济于事.

我知道这有点模糊 - 但是想知道是否有人有任何处理这个的建议?这个相同的代码在模拟器中完美运行,但每次在我的实际设备上都会失败,即使在我的应用程序未安装和重新安装之后也是如此.鉴于这是我的实际手机,我有点保持沉默,希望它解决了这个问题,并且不愿意将此应用程序发布到市场,因为这个问题困扰着我.

更新:另外一点,我使用的是未经身份验证的渠道,因此我的基于云的服务没有安装证书.

更新#2:此外,我刚尝试将Microsoft Phone Push Recipe部署到我的设备上,它也抛出相同的异常.

小智 6

因此,根据您的评论,我了解它可以在您的模拟器上运行但不能在您的手机上运行吗?你有没有机会在另一个/之前的申请中使用频道名称?

问题是模拟器重置回它的默认状态,它关闭,你的手机没有.特定通道名称只能由单个应用程序使用.因此,如果频道名称在同一部手机上被另一个应用程序使用,那么它仍然会注册到该应用程序,并且您无法通过应用程序访问它.

相反,一个应用程序也可以注册不超过一个通道,所以如果已经有一个与其相关联的名称,则在取消注册旧的并重新启动设备之前,您无法注册新的通道.此外,无法请求将哪个频道与您的应用相关联.

最后,当我陷入这个循环时,我更改了通道的名称和我在WMAppManifest.xml中注册的应用程序ProductID,它再次起作用

<App xmlns="" ProductID="{d57ef66e-f46c-4b48-ac47-22b1e924184b}"
Run Code Online (Sandbox Code Playgroud)

更新 我的电脑本周末崩溃,感谢上帝的WHS和备份.无论如何下面是我的源代码.我注意到两个不同之处.

  1. 首先,我创建了一个名为的方法RepeatAttemptExecuteMethod(),我将整个执行代码作为委托传递给我.最后浮动的10个是它必须重试的次数.如果你.Open每5秒只重试一次方法,差异可能在于我也再次调用Find和New方法......

  2. 我看到的另一个区别是我的代码假定_appChannel.ChannelUri可以为null.在这种情况下,它等待通道引发事件,然后将工作与实际通道相关联.但是,由于您的样本代码没有做任何类似的工作,我怀疑它将是您正在寻找的

    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();
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)


小智 0

@slaad ..这里有一些我会检查的事情,除非你已经尝试过这些:

  1. 您的实际设备确实具有数据连接,对吧?呵呵 :)
  2. 您如何将现有通道存储在隔离存储中?确保您的 Find() 正在工作并且您没有尝试重新创建导致异常的存在通道。
  3. 检查您的频道创建是否存在域名或证书问题。试试这个链接
  4. 对照此检查流程的每一步

抱歉,没有比这更多的帮助了。