0 out of 1 rated this helpful - Rate this topic

How To: Service Bus Notification Hubs (Windows Store Apps)

noteNote
Notification Hubs are available in the Windows Azure Service Bus as a preview feature in January 2013. It is expected to transition to General Availability (GA) in midyear 2013.

noteNote
As a result of the improvements made to Notification Hubs, the SDK you downloaded before April 2013 will not work with the new Notification Hubs. Conversely, the current SDK will not work with Notification Hubs created before April 2013. Please start using the new Notification Hubs with the new SDK to take full advantage of the new features, such as optimistic concurrency control. Support for Notification Hubs created before April 2013 will end when Notification Hubs transitions to GA.

Service Bus Notification Hubs are Service Bus entities that enable a user to send device push notifications through third-party application platforms, including:

  • The Windows Push Notification Services (WNS) for Windows 8.

  • The Apple Push Notification service (APNs).

This guide describes how to perform the tasks required to implement a complete solution that uses Notification Hubs:

  • Create and configure a Notification Hub.

  • Set up a Windows Store App (C#) that registers to receive push notifications.

  • Set up a .NET back-end service to push notifications through WNS.

  • Use advanced features (template registrations, tag-level security).

Support for using Notification Hubs in Windows Azure Mobile Services is coming soon.

noteNote
Service Bus Notification Hub Tutorial (Windows Store Apps) provides more detailed step-by-step instructions on how to broadcast push notifications to a Windows Store application. Also, the Windows Azure Service Bus Notification Hubs topic provides high-level explanations of the major features as well as architectural guidance.

Prerequisites

In order to perform the tasks explained in this tutorial, you must have the following:

  • A Windows Store development account.

  • Service Bus .NET Preview SDK. The SDK is a NuGet package that contains Service Bus preview features, and you can download it here. The package is ServiceBus preview features, and it contains a new Service Bus library called Microsoft.ServiceBus.Preview.dll. In order to use Notification Hubs, use this library instead of the production version (Microsoft.ServiceBus.dll).

  • Service Bus WinRT Managed SDK. You can download this SDK here.

Notification Hub Main Concepts

A notification hub is a Service Bus entity that enables you to send push notifications to devices through platform-native notification systems. Each notification hub contains the credentials that are required to connect to the PNSs and send push notifications to a specific app.

A Notification Hub contains one credential for each supported platform. This level of security enables it to send push notifications to a single app for each platform (in case of APNs, only to one of the environments, Sandbox or Production). Also, a notification hub provides a context for security.

At a high level, notification hubs are used in the following way:

  1. A Notification Hub is provisioned with credentials for at least one platform.

  2. A registration is created on the Notification Hub (eventually associated to a set of tags).

  3. A message that contains the notification content is sent to the Notification Hub. The message can be labeled with a tag.

  4. The Notification Hub pushes the notification content to all registrations with the specified tag.

While Notification Hubs provide a security context and are closely related to the app, registrations associate platform-specific handles (for example, tokens for APNs, ChannelURIs for WNS) to tags. Tags provide a way to target specific sets of devices/handles. For more high-level information, see the Windows Azure Service Bus Notification Hubs topic.

Create and configure a Notification Hub

This section creates and configures a Notification Hub with your WNS credentials.

Register your application with Windows Store

In order to send push notifications through WNS, your application must be registered in Windows Store. You can follow steps 1, 2, and 3 outlined in http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868206.aspx. After completing these steps, you should have a Package SID and a Client Secret, which you use later to configure your Notification Hub.

Create a Namespace

A Service Bus namespace can contain multiple entities (queues, topics, relays, and Notification Hubs), and provides a root security context. Users create namespaces on the Windows Azure Management Portal. Once a namespace is created, entities can be created, updated, and deleted programmatically using the .NET Service Bus Preview SDK listed in the “Prerequisites” section.

Create and configure a Notification Hub

Using the Windows Azure Management Portal, you can create a notification hub and configure it to send push notifications to a Windows Store application.

  1. Log on to the Windows Azure Management Portal (http://manage.windowsazure.com/)

  2. In the bottom left corner, click New.

  3. Select App Services->Service Bus Notification Hub->Quick Create.

  4. Select a name for the notification hub, a region, and the namespace in which this notification hub will be created (if there are no namespaces available a new one with the desired name is provisioned).

    Use Quick Create to create a hub
  5. Click the label “Create a new Notification Hub” at the bottom right of the screen.

  6. Now, under the Service Bus tab on the left navigation pane, click the created namespace. The notification hub should appear in the list.

    New hub created in the Azure Portal
  7. Click the notification hub, and then click the configure tab on the top.

    Configure the new hub
  8. Insert the Package SID and Client Secret obtained from your Windows Store, and then click Save in the bottom toolbar.

Client Application

This section describes how to register to a Notification Hub from your client app.

Associate your client app project with the Windows Store

In the previous section, you registered your app in the Windows Store. Now you must associate the modern app project with the app you created in the store. This association configures the Package.appmanifest with the correct package identifier issued by the Windows Store.

  1. In Visual Studio, right-click the Windows Store app project in Solution Explorer, and then click Store, then Associate App with the Store.

  2. Follow the wizard steps.

Configure your client application to use a Notification Hub

First, add a reference to the Service Bus WinRT Preview SDK:

  1. Download the following .zip file: Service Bus WinRT Preview SDK.

  2. In Solution Explorer, right-click References, and then click Add Reference. Browse to the location in which you unzipped the file, and click Microsoft.WindowsAzure.Messaging.Managed.dll.

  3. If you want to use toast notifications, remember to enable them in the Package.appmanifest.

    Push Notifications Package

In order to register to a Notification Hub to receive push notifications, use the NotificationHub client class. This class must be a singleton in your client app. One way to instantiate a singleton instance is to store it as a parameter in the App class (defined in the file App.xaml.cs), as shown here:

Using Microsoft.WindowsAzure.Messaging;
sealed partial class App : Application
{
    …
    private NotificationHub notificationHub;
    
    public App()
    {
        …
        notificationHub = new NotificationHub(<notificationHubPath>, <connectionString>);
        …
    }

This code uses a connection string to connect to a Notification Hub. To generate a connection string, follow these steps:

  1. In the Windows Azure Management Portal, click Service Bus in the left navigation pane, and then select your namespace. Note the name of your namespace, in this case notificationhub-ns.

    New hub created in the Azure Portal
  2. Click your notification hub name. Now that you are in the notification hub dashboard, click View SAS Key on the bottom toolbar.

    Connect to your notification hub
  3. Copy the value of the key named DefaultListenSharedAccessSignature.

  4. You can generate a connection string to connect to this notification hub with the following method:

    ConnectionString.CreateUsingSharedAccessSecretWithListenAccess(new Uri("sb://<namespace name>.servicebus.windows.net"), "<listen access key value>");
    
    noteNote
    In the preceding code, Service Bus credentials are embedded in your client app code. . Note that embedding credentials in the app removes the ability to secure registration to specific tags. To understand and implement the correct approach for your app, see the “Security” section of Windows Azure Service Bus Notification Hubs.

Register for Native Notifications

One way to send push notifications is to have the backend specify the platform-specific payload of the notification, called native notifications. Your client app registers for native notifications by creating a native registration in the Notification Hub. This approach makes your client app responsible only for creating this registration in the Notification Hub, and keeping it up-to-date with the latest ChannelUri and tags. The benefits of this approach are a simple client-side configuration, and full control of the format of the notifications in the backend. The disadvantages are the need to create and send multiple platform-specific payloads from your back-end app, and a more complex implementation of per-user personalization of notifications. For more information about native vs. template registrations, see Windows Azure Service Bus Notification Hubs.

noteNote
The Windows Notification Service uses the ChannelUri to identify a specific installation of your app. See Push notification overview (Windows Store apps).

The following is simple code that ensures that a client is registered for native notifications and that the registration is kept updated with the latest ChannelUri.

sealed partial class App : Application
{
    private NotificationHub notificationHub;
    …
    public App()
    {
    …
        notificationHub = new NotificationHub(connectionString, "notificationhub");
        InitNotifications();
    }
    …
    private async void InitNotifications()
    {
        var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
        await hub.RefreshChannelUriAsync(channel.Uri);
        await notificationHub.CreateNativeRegistrationAsync();
    }

This code performs two main functions:

  • It ensures that the registrations in the Notification Hub are updated with the latest ChannelUri for the application.

  • If no native registration is present, it creates a native registration with no tags.

Refresh Channel Uris. ChannelUris can change at any moment. In order to keep your client app registrations in the Notification Hub updated, the device must refresh them with the following code every time the app starts. Usually, it is called from the OnLaunched method of App.xaml.cs, as in the preceding code.

Perform all registration operations after calling the RefreshChannelUriAsync method.

hub.RefreshChannelUriAsync(channel.Uri);

The RefreshChannelUriAsync method ensures that all existing registrations for your app main tile are updated with the provided ChannelUri. Please refer to the section “Send Notifications to Secondary Tiles” for updating the ChannelUris of secondary tiles.

noteNote
The RefreshChannelUriAsync method does not register the device for notifications. It only ensures that the ChannelUri stored in Service Bus is up-to-date. In order to receive notifications, the client must register for either native or template notifications.

Register for Native Notifications. In order to create a native registration, your client app invokes the CreateRegistration methods on the NotificationHub class. You might have to create registrations in response to user preferences and/or business logic on the client. The following code creates a native registration.

await notificationHub.CreateNativeRegistrationAsync();

If the registration must contain some tags (for example, news categories or a user name), you can use overloads of the Create method:

await notificationHub.CreateRegistrationNativeAsync(tags: new string[] {"Yankees"});

Note that the above method overwrites the previous set of tags (if present).

You can implement more complex logic by using the following methods of the NotificationHub class: RegistrationExists, GetRegistration, DeleteRegistration, and UpdateRegistration.

Register for Template Notifications

The previous section explained the advantages and disadvantages of using native registrations. Template registrations specify a template in order to convert platform-agnostic notifications into a platform-specific personalized notification. Your client app can opt to use template registrations instead, or in addition to, native registrations. Using template registrations, you can move the platform-specific part of push notifications from the app backend to the client app. The main advantages of this approach are a platform-agnostic back-end code, and the possibility of per-user personalization. The disadvantage is that changing the platform-specific payload of a notification (for example, ToastText01 versus ToastText02) requires updating a registration. Usually template registrations are a good fit for notifications that have always the same format and target multiple platforms. For more information about native vs. template registrations, see Windows Azure Service Bus Notification Hubs.

Templates. A template is a string that represents the body of the notification you want to send to the device. The template refers to properties in the incoming message with a simple expression language. An example is the following:

<toast>
  <visual>
    <binding template=\"ToastText01\">
      <text id=\"1\">$(property1)</text>
    </binding>
  </visual>
</toast>

Note the use of the expression $(property1).

When the back-end sends a message that reaches this registration with a property called property1 with value value; for example, with the code snippet shown in the section “Send a Template Notification,” Service Bus sends a push notification that contains value instead of the expression, as shown here:

<toast>
  <visual>
    <binding template=\"ToastText01\">
      <text id=\"1\">value</text>
    </binding>
  </visual>
</toast>

A client can create a template registration with the following code snippet:

await hub.CreateTemplateRegistrationForApplicationAsync(buildToastTemplate(), "myToastRegistration", new string[] {"tag"});
…
private XmlDocument buildTextToastTemplate()
{
  var template = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
  var textNode = template.SelectSingleNode("//text[@id='1']") as XmlElement;
  if (textNode != null)
    {
      textNode.InnerText = "$(property1)";
    }
  return template;
}

Note that the method to create a template registration takes a registration name parameter (myToastRegistration in this code). This process enables a single client app to create multiple registrations, each with different templates and sets of tags. For more information, see the section “Creating Multiple Registrations.”

Also, the preceding template is created using the Windows RT helper classes. It can also be created by parsing an XmlDocument from the XML string reported earlier. Service Bus also provides helper methods to create the templates, in the class NotificationXmlBuilder.

var template = NotificationXmlBuilder.CreateToastText01Xml("$(property1)");
noteNote
Aside from having an additional property (the template), template registrations work in the same way as native registrations, in the sense that they must be kept updated with the latest ChannelUri and tags. It follows that you must still call the RefreshChannelUriAsync method every time your client app launches.

Expression Language. The following table shows the language allowed in templates.

 

Expression Description

$(prop)

Reference to an event property with the given name. Property names are not case-sensitive. This expression resolves to the property’s text value or to an empty string if the property is not present.

$(prop, n)

As above, but the text is explicitly clipped at n characters. For example, $(title, 20) clips the contents of the title property at 20 characters.

.(prop, n)

As above, but the text is suffixed with three dots as it is clipped. The total size of the clipped string and the suffix does not exceed n characters. .(title, 20) with an input property of “This is the title line” results in This is the title….

%(prop)

Similar to $(name), except that the output is URI encoded.

#(prop)

Used in iOS templates.

This function works the same as $(prop) specified above, except when used in JSON templates (such as Apple templates). In this case, if this function:

  • is not surrounded by ‘{‘,’}’ (e.g. ‘myJsonProperty’ : ‘#(name)’), and

  • it evaluates to a number in Javascript format, i.e. regexp: (0|([1-9][0-9]*))(\.[0-9]+)?((e|E)(+|-)?[0-9]+)?,

then the output JSON is a number.

For example, ‘myJsonProperty’ : ‘#(name)’ becomes ‘myJsonProperty’ : 40 (and not ‘40‘).

‘text’ or “text”

A literal. Literals contain arbitrary text enclosed in single or double quotes.

expr1 + expr2*

The concatenation operator that joins two expressions into a single string.

The expressions can be any of the preceding.

When using concatenation, the entire expression must be surrounded with {}, e.g. {$(prop) + ‘ - ’ + $(prop2)}.

Creating Template Registrations

Because an app might create multiple template registrations, the method CreateTemplateRegistrationAsync has a required parameter called templateName. For example, if an app wants one registration for native notifications and one with a toast template, the following snippet can be used: When using the method CreateRegistrationForApplication, the NotificationHub class creates a registration called $default. To create multiple registrations, call the overloaded method with a registration name specific to the registration. For example, if an app wants one registration for native notifications and one with a toast template, the following snippet can be used:

await notificationHub.CreateNativeRegistrationAsync(new string[] {"Yankees"});
await notificationHub.CreateTemplateRegistrationAsync(buildToastTemplate(), "toastTemplate", new string[] {"RedSox"});

The first statement ensures that a native registration for tag “Yankees” is present. The second statement ensures that a registration called toastTemplate exists and overwrites the tags and template with the provided ones.

All methods that perform registration management for template registrations require a template name (create, get, exists, and delete).

Application Back-end

In order to send push notifications, your app back-end must connect to a Notification Hub.

Configure your app back-end to use a Notification Hub

Accessing Notification Hubs in Service Bus from .NET requires an updated client library. You can download this package via NuGet. The package is called ServiceBus preview features and it contains a new Service Bus library named Microsoft.ServiceBus.Preview.dll. To use Notification Hubs, use this library instead of the production version (Microsoft.ServiceBus.dll).

  1. Open your back-end app project in Visual Studio.

  2. In Solution Explorer, right-click References, and select Manage NuGet packages. Search for Service Bus preview, and install the package called Service Bus preview features.

  3. At the top of any C# file in which you want to use Service Bus, add the following using statements:

using System.Runtime.Serialization;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.ServiceBus.Notifications;

Generate a connection string. To access a Notification Hub, you must have a connection string. The following procedure obtains from the portal the information required to gain full access to the Notification Hub you created in the section “Create and configure a Notification Hub.”

  1. In the Windows Azure Management Portal, click Service Bus in the left navigation pane, and then click your namespace. Note the name of your namespace.

  2. Click the Notification Hub you configured for your app.

  3. From the notification hub dashboard, click View SAS Key on the bottom toolbar.

    Connect to your notification hub
  4. Copy the value of the key named DefaultFullSharedAccessSignature.

  5. You can generate a connection string to connect to this notification hub by using the following method:

ServiceBusConnectionStringBuilder.CreateUsingSharedAccessKey(new Uri("sb://<namespace name>.servicebus.windows.net"), NotificationHubDescription.DefaultFullSasRuleName, "full access key value");

For example,

ServiceBusConnectionStringBuilder.CreateUsingSharedAccessKey(new Uri("sb://NotificationHub-ns.servicebus.windows.net "), NotificationHubDescription.DefaultFullSasRuleName, " OMm:M+aC}{566I8t");

Using ACS. Using the preceding connection string is the preferred method to access a notification hub. If you want to use ACS, you can connect using the connection string provided in your namespace.

  1. In the portal, click Service Bus in the left navigation pane, and then click the namespace that contains the notification hub you want to use.

  2. In the bottom toolbar, click Access Key, and copy the connection string field.

    Portal Connect to Namespace

Send a Windows Store native notification from your app backend

Make sure that your client application is correctly set up to create a native registration as explained in the section “Register for Native Notifications.” In order to send a push notification, your app backend contacts the notification hub you just created.

var hubClient = NotificationHubClient.CreateClientFromConnectionString(connectionString, "<notification hub path>");
var notificationBody = WindowsNotificationXmlBuilder.CreateToastText01Xml("Hello!");
hubClient.SendWindowsNativeNotification(notificationBody);

This code sends a notification to all Windows registrations. In order to target a specific set, one overload of the Send method takes a tag parameter.

hubClient.SendWindowsNativeNotification(notificationBody, "destinationTag");

For more information about how to use tags in your application, see Windows Azure Service Bus Notification Hubs.

Send a Template Notification

Make sure that your client app is correctly set up to create a template registration as explained in the section “Register for Template Notifications.” In order to send a registration to template registrations, your app backend sends a platform-agnostic message that contains a dictionary of properties. The required properties depend on the templates used in the registrations.

IDictionary<string, string> properties = new Dictionary<string, string>();
properties.Add("property1", "value");
hubClient.SendTemplateNotification(properties, "destinationTag");

Advanced Topics

This section describes the features required for advanced scenarios, using Notification Hubs.

Send Notifications to Secondary Tiles

For Windows Store client apps, sending notifications to secondary tiles is the same as sending them to the primary one. Both native and template registrations are supported. The only difference is that secondary tiles have a different ChannelUri, which the Service Bus SDK on your client app handles transparently.

At a high level, all the information provided in the previous sections work with secondary tiles by calling the corresponding methods on the objects exposed on the dictionary property SecondaryTiles of NotificationHub. For example:

await notificationHub.SecondaryTiles["myTileId"].RefreshChannelUriAsync(channel.Uri)
await notificationHub.SecondaryTiles["myTileId"].CreateNativeRegistrationAsync(new string[] {"Yankees"});
await notificationHub.SecondaryTiles["myTileId"].CreateTemplateRegistrationAsync(buildToastTemplate(), "toastTemplate", new string[] {"RedSox"});

The SecondaryTiles dictionary uses the same tileId that is used to create the SecondaryTile object in your Windows Store app.

Refresh ChannelUri. As with the primary ChannelUri, ChannelUris of secondary tiles can change at any moment. In order to keep the client app registrations in the Notification Hub updated, the device must refresh them with the current ChannelUris of the secondary tiles using the following code every time the app starts.

notificationHub.SecondaryTiles["myTile"].RefreshChannelUriAsync(secondaryTileChannel.Uri);

The RefreshChannelUriAsync method ensures that all existing registrations for your secondary tile are updated with the specified ChannelUri.

noteNote
Secondary tiles can be deleted by the user when the app is inactive. If those tiles can have registrations, remember to delete them when your app starts.

The following code refreshes the ChannelUris for all existing tiles and deletes the registrations for tiles that no longer exist.

foreach (var tileId in hub.SecondaryTiles.Keys)
{
    if (SecondaryTile.Exists(tileId))
    {
        var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForSecondaryTileAsync(tileId);
        hub.SecondaryTiles[tileId].RefreshChannelUriAsync(channel.Uri);
    } else
    {
        hub.SecondaryTiles[tileId].DeleteRegistrationsAsync();
    }
}

Creating registrations. All the management methods have variants for secondary tile registrations:

await notificationHub.SecondaryTile["myTileId"].CreateNativeRegistrationAsync(new string[] {"Yankees"});
await notificationHub. SecondaryTile["myTileId"].CreateTemplateRegistrationAsync(buildToastTemplate(), "toastTemplate", new string[] {"RedSox"});
noteNote
When creating a new secondary you must call RefreshChannelUriAsync before creating and deleting registrations. Also, you must use the same tileId used to create the tile.

Sending notifications. Sending notifications to secondary tiles does not change. Note that secondary tiles can only accept tile and badge notifications (no toasts).

Registration management from your app backend

The Service Bus .NET Preview SDK provides methods to create, update, and delete registrations from your app backend. These methods require your client app to pass the ChannelUris to the backend explicitly. The backend is then responsible for refreshing all registrations with the current token.

The main difference between managing registrations in the client app and in the app back-end is in how you refer to specific registrations. In the client app, you always refer to the registrations of the current device. On the app back-end, you can retrieve registrations based on the registrationId property, and tags. Every registration has a registrationId that uniquely identifies it. You can retrieve the registrationId when you create it. For example:

var r = hubClient.CreateWindowsNativeRegistration("<channelUri>", new string[] {"tag"});
string registrationId = r.RegistrationId;

You can then retrieve and update a registration using its registrationId, as in this example:

var r = hubClient.GetRegistration<WindowsRegistrationDescription>(registrationId);
r.Tags.Add("newTag");
hubClient.UpdateRegistration(r);

Another option is to refer to registrations by tag. This is especially useful when using tags as installation ids or user IDs. The following code retrieves all registrations tagged with the tag userId:Alice.

var registrations = hubClient.GetRegistrationsByTag("userId:Alice", 0, 100);

Note that you must provide skip and count parameters, and you might have to make sure that you only retrieve the expected number of registrations.

Refresh ChannelUris. As with registration management from the client, you must make sure that ChannelUris in registrations are up to date. To do this, update registrations one by one, as in the following code.

var r = hubClient.GetRegistration<WindowsRegistrationDescription>(registrationId);
r.ChannelUri = channel.Uri
hubClient.UpdateRegistration(r);

Or, if you have the old ChannelUri, use a helper method that updates all registration from an old ChannelUri to a new one. For example:

hubClient.UpdateRegistrationsWithNewPnsHandle("<old channelUri>", "<new channelUri>");

When the registration management is completed in your app back-end, no reference to Notification Hubs has to be present in your client app: your app backend has full responsibility for creating the registrations for the clients and keeping them updated.

noteNote
Registrations automatically expire if not regularly updated (the expiration time is reported in the Windows Azure Management Portal and in the registration itself when retrieved programmatically).

Additional Resources

Did you find this helpful?
(1500 characters remaining)

Community Additions

ADD
© 2013 Microsoft. All rights reserved.