HttpNotificationChannel Open() 抛出 InvalidOperationException(“无法打开通道”)

发布于 2024-10-19 11:29:06 字数 1407 浏览 3 评论 0原文

我正在编写一个 Windows Phone 7 应用程序,它利用推送通知,并有一个类负责管理 MS 通知服务器和我在云中的服务之间的交互。但是,当我尝试在设备上打开通道时,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));
    };
  }
}

我不确定 MSDN 中“尝试再次打开通道”的含义。我将对 Open() 的调用包装在 try/catch 中,并在两次尝试之间暂停 5 秒,但没有成功。我还在整个方法中尝试了相同的方法(即每次抛出时都调用 HttpNotificationChannel.Find() ),但无济于事。

我知道这有点模糊 - 但想知道是否有人对处理这个问题有任何建议?相同的代码在模拟器中完美运行,但每次在我的实际设备上都会失败,即使在卸载并重新安装我的应用程序后也是如此。鉴于这是我真正的手机,我有点不愿意进行硬件重置,希望它能解决这个问题,并且由于这个问题困扰着我,所以不愿意将应用程序发布到市场。

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

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

I'm writing a Windows Phone 7 application which utilises Push Notifications and have a class which is responsible for managing interactions between the MS Notification Servers and my service in the cloud. However when I'm attempting to open the channel on my device HttpNotificationChannel is throwing an InvalidOperationException with the message "Failed to open channel". According to MSDN I should try opening the channel again.

My snippet of code to open the push notification is following the standard pattern of;

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));
    };
  }
}

I'm not sure exactly what MSDN means by "try opening the channel again". I've wrapped the call to Open() in a try/catch and snoozing 5 seconds between attempts but it doesn't succeed. I've also tried the same approach around the entire method (ie. Do the call to HttpNotificationChannel.Find() each time it throws) to no avail.

I know this is a tad bit vague - but was wondering if anyone has any suggestions on handling this? This same code works flawlessly in the emulator, but fails every time on my actual device, even after an un-install and re-install of my application. Given that this is my actual phone, I'm a little reticent to do a hardware reset in the hope that it solves this issue, and don't feel comfortable releasing the application to the marketplace with this issue haunting me.

Update: An additional point, I'm using an unauthenticated channel, so there's no certificate installed for my cloud-based service.

Update #2: Further, I just tried deploying the Microsoft Phone Push Recipe to my device and it's also throwing the same exception.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦言归人 2024-10-26 11:29:06

因此,从您的评论中我了解到它确实可以在您的模拟器上运行,但不能在您的手机上运行,​​对吧?
您是否曾在另一个/之前的应用程序中使用过该频道名称?

问题是模拟器每次关闭时都会重置回默认状态,而您的手机则不会。特定通道名称只能由单个应用程序使用。因此,如果频道名称已被同一手机上的另一个应用程序使用,那么它仍然注册到该应用程序,并且您无法从您的应用程序访问它。

相反,一个应用程序也只能注册一个频道,因此,如果已有一个频道与其关联,则您无法注册新频道,除非您取消注册旧频道并重新启动设备。此外,也无法请求哪个频道与您的应用程序关联。

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

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

更新
我的电脑这个周末崩溃了,感谢上帝的 WHS 和备份。
无论如何,下面是我的源代码。我注意到两个差异。

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

  2. 我看到的另一个差异是我的代码假设_appChannel.ChannelUri 可以为 null。在这种情况下,它会等待通道引发事件,然后执行与实际通道相关的工作。但由于您的示例代码没有执行任何此类工作,我怀疑这将是您正在寻找的

    protected override void Load(PhoneApplicationPage 父级)
    {
        Verkeer.Helper.ExternalResources.RepeatAttemptExecuteMethod(() =>; 
        {
            _appChannel = HttpNotificationChannel.Find(CHANNELNAME);
            如果(_appChannel == null)
            {
                _appChannel = new HttpNotificationChannel(CHANNELNAME);
                SetUpDelegates();
            }
            别的
            {
                SetUpDelegates();
                //if (_appChannel.ChannelUri != null) this.NotificationChannel = _appChannel.ChannelUri;
            }
            if (_appChannel.ChannelUri != null) this.NotificationChannel = _appChannel.ChannelUri;
            别的
            {
                尝试
                {
                    _appChannel.Open();
                }
                抓住 { }
            }
    
            BindToShellTile();
    
            App.ViewModel.TrafficInfo.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(TrafficInfo_PropertyChanged);
    
            if (App.ViewModel.TrafficInfo.TrafficImage != null && this.NotificationChannel != null)
            {
                创建瓷砖();
            }
        },10);
    }
    
    私有无效 BindToShellTile()
    {
        if (!_appChannel.IsShellTileBound && App.ViewModel.PanItemSettings.AutomaticallyUpdateTile)
        {
            集合 ListOfAllowedDomains = new Collection; { 新的 Uri("http://m.anwb.nl/") };
            _appChannel.BindToShellTile(ListOfAllowedDomains);
        }
    }
    
    
    void TrafficInfo_PropertyChanged(对象发送者,System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "TrafficImage")
        {
            if (App.ViewModel.PanItemSettings.AutomaticallyUpdateTile && this.NotificationChannel != null)
            {
                创建瓷砖();
            }
        }
    }
    

So from your comment I understand that it does work on your emulator but not on your phone right?
Did you by any chance use the channel name in another/prior application?

The thing is that the emulator reset back to it's default state everyime it closes, your phone does not. A particular channel name can only be used by a single application. So if the channel name was used by another application on the same phone before it is still registered to that app and you can't access it from your app.

Conversely an app can also regsiter no more than one channel so if there is allready one by another name associated with it you cannot register a new one until you unregister the old one and reboot your device. Also there is no way to request which channel is associated with your app.

Ultimately when I got stuck in this loop I changed the name of the channel and my applications ProductID registered in the WMAppManifest.xml and it worked again form me

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

Update
My computer crashed this weekend, thank god for WHS and backups.
Anyway below is my sourcecode. I notice a two differences.

  1. First off I created a method called RepeatAttemptExecuteMethod() to which I pass the entire executing code as a delegate. The 10 floating somewhere at the end is the amount of times it has to retry. If you only retried the .Open method every 5 seconds the difference might be in that I also call the Find and New methods again...

  2. Another difference I see is that my code assumes that the _appChannel.ChannelUri can be null. In which case it waits for the channel to raise an event and then does the work asociated with a actual channel being there. But since your samplecode doesn't do any of that sort of work I doubt it will be what you are looking for

    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();
            }
        }
    }
    
夜光 2024-10-26 11:29:06

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

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

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

@slaad .. here are few things that I would check, unless you have already tried these:

  1. Your actual device does have data connectivity, right? doh :)
  2. How are you storing an existing Channel in Isolated Storage? Make sure your Find() is working & that you are not trying to recreate a channel that exists leading to exception.
  3. Check if your Channel creation has issues with domain name or certs. Try this link
  4. Check every step of your process against this

Sorry, not being of much more help than this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文