HttpNotificationChannel Open() throwing InvalidOperationException ("Failed to open channel")
Asked Answered
S

2

6

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.

Swordtail answered 1/3, 2011 at 11:51 Comment(0)
S
6

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();
            }
        }
    }
    
Secunderabad answered 2/3, 2011 at 9:29 Comment(16)
@Leon: That's correct, it works fine on the emulator. I've tried uninstalling the existing version of the app, rebooting, changing the ProductID and channel name, and re-deploying the app but still running into the same issue. When you were facing this problem was HttpNotificationChannel.Find() returning null? Because for me it is.Swordtail
Yes it did. I assume because the actual channel was no longer there but the registration pointing to it was. The only way I could get it removed was by removing the app, rebooting the phone, changing the app ID's, force rebuilding it, then force redeploying itSecunderabad
Btw isn't the Microsoft Phone Push Recipe a send notification Recipe and not a receiving one?Secunderabad
The helper library is for the server side, but the recipe download includes a complete client/server demo solution.Swordtail
Hrm, tried that, I cleaned the solution, nuked the debug directories, then did a "Deploy Solution" (Presume that's what you mean by force redeploy), then debug. No luck. Going a tad bit mad here...Swordtail
Odd, what happens if you call the HttpNotificationChannel.Close method with your channel name? Also did you remove the application from your phone and rebooted the phone prior to cleaning and redeploying the solution? FinallySecunderabad
Also have you seen this article on the various types of InvalidOpertationExceptionsSecunderabad
Yup - tried HttpNotificationChannel.Close() on all the variants of the channel name I believe I've used. I also whipped up a test with the emulator; Created an app and Open()'d a channel "Channel1", closed the app, redeployed and Open()'d channel "Channel2". This succeeded without issue which makes me think it's not to do with a spurious channel name in being used at one stage. And yes, did a reboot before clean / redeploy of solution. The MSDN link you posted is the same one I posted in the question - it's not terribly useful :(Swordtail
Sorry for missing your link on that, that was rather daft. This doesn't make much sense to m.e allow me to get my source code tonight and post that. Maybe a comparison will help hereSecunderabad
@Leon: No worries about missing it... I'm just surprised by how useless the article is. Any luck digging up your source code? Is it any different from the prototypical example I pasted?Swordtail
@Slaad, soz for that, had to fix my coputer, I updated my response aboveSecunderabad
@Leon: Your code is pretty similar to mine. I don't think your code will ever re-try as the call that throws for me is the .Open() which you've wrapped in a try/catch with no re-throw. Unless something in BindToShell() will throw when .Open() fails / or you're working on the assumption that it's okay for .Open() to fail.Swordtail
Ah yes interesting on that is. If the open fails I will try to reopen it later when the code explicitly needs it. (I needed to make this conditionally in order to pass certification) so when a user pushes the update tile button it tries to open the channel if the notification channel is nullSecunderabad
geez it's been a while since I wrote my code I can't rememeber half of itSecunderabad
Also I read on XDA developers that the NoDo update is surpossed to fix some problems with Push Notifications. Maybe we can wait till mid next week to find out?Secunderabad
Ah, interesting point... the emulator is already running NoDo, which may explain why it's still happily plugging away. I guess for now I wait and see - not much else I can do.Swordtail
R
0

@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.

Remise answered 1/3, 2011 at 14:7 Comment(3)
Yup - I've tried setting my device to airplane mode and connecting to my WiFi to ensure it's not my 3G data provider causing issues.Swordtail
To clarify, the Find() method is the static one provided on WP7 HttpNotificationChannel class, I'm not explicitly doing any storage of the channel. Also, this persists after a re-install of the app, so there shouldn't be a lingering channel. I've also tried Close()ing the channel, restarting the app, and seeing if that helps. No dice. I'm using an unauthenticated channel (ie. No certs involved), so 3 is out. On the emulator the creation process works flawlessly, so dubious about #4, but will go through it again step by step.Swordtail
@curiosity I no longer have the issue but did not make any code changes to resolve it. I imagine either NoDo or the Mango beta has fixed it. Or possibly just the act of flashing my phone to install either of those. Using the same pattern as shown in my original question without issue now.Swordtail

© 2022 - 2024 — McMap. All rights reserved.