Windows Azure Mobile Services has great built-in support for
making Push Notifications; however there’s a better more scalable option using
the Notifications Hub which is part of the Service Bus group of services.
We can call the hub from external backend services using the
Windows Azure Service Bus SDK (NuGet PM> Install-Package
WindowsAzure.ServiceBus) and this is fairly well documented; however if you
want to do a direct replacement for the build-in Push Notifications using
Notifications Hub, it’s not so well documented. I did some digging in the
source to work out how to use it: https://github.com/WindowsAzure/azure-sdk-for-node
In our Mobile Services scripts we can make use of NPM
packages which we install ourselves and pre-installed packages like the Windows
Azure SDK for Node which we will use for calling the Hub.
Accessing the Notifications Hub
We need two things to allow us to connect to the hub and
those are the DefaultFullSharedAccessSignature which you can get from the
Notifications Hub Dashboard and the Hub name. We can declare these as variables
like this:
var
CONNECTION_STRING =
"Endpoint=sb://myapp.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=XXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=";
var
HUB_NAME = "MyHubName";
Now to interact with the Notifications hub, we get a
reference to the Azure package like this:
var
azure = require("azure");
Then create a NotificationHubService like this:
var
notificationHubService = azure.createNotificationHubService(HUB_NAME,
CONNECTION_STRING);
All the native PNS send methods have prototypes similar to
this:
MpnsService.prototype.send
= function (tags, payload, targetName, notificationClass, optionsOrCallback,
callback)
The Notifications class is the batching interval (how quick
it’s sent).
Windows Phone MPNS Notofications
Following are examples of sending toast and tiles to Windows
Phone apps using the MPNS provider:
function
sendToastHubMpns(text1, text2, tagExpression)
{
var azure = require("azure");
var notificationHubService =
azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);
var toast = "<?xml
version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification
xmlns:wp=\"WPNotification\">" +
"<wp:Toast>" +
"<wp:Text1>" +
text1 + "</wp:Text1>" +
"<wp:Text2>" +
text2 + "</wp:Text2>" +
"</wp:Toast> " +
"</wp:Notification>";
notificationHubService.mpns.send(tagExpression, toast,
"toast", 2, function(error) {
if (error) {
console.error(error);
}});
}
function
sendTileHubMpns(backTitle, backContent, tagExpression)
{
var azure = require("azure");
var notificationHubService =
azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);
var tile = "<?xml
version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification
xmlns:wp=\"WPNotification\" Version=\"2.0\">" +
"<wp:Tile Template=\"FlipTile\">"
+
"<wp:BackTitle>"
+ backTitle + "</wp:BackTitle>" +
"<wp:BackContent>" + backContent +
"</wp:BackContent>" +
"<wp:WideBackContent>" + backContent +
"</wp:WideBackContent>" +
"</wp:Tile> " +
"</wp:Notification>";
notificationHubService.mpns.send(tagExpression, tile, "token",
1, function(error) {
if (error) {
console.error(error);
}});
}
Windows 8 WNS Notifications
Following are examples of sending toast, tile and badge
notifications to Windows 8 apps using the WNS provider:
function
sendToastHubWns(text1, text2, text3, tagExpression)
{
var azure = require("azure");
var notificationHubService =
azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);
var toast = "<toast>" +
"<visual>" +
"<binding
template=\"ToastText04\">" +
"<text
id=\"1\">" + text1 + "</text>" +
"<text
id=\"2\">" + text2 + "</text>" +
"<text
id=\"3\">" + text3 + "</text>" +
"</binding>" +
"</visual>" +
"</toast>";
notificationHubService.wns.send(tagExpression, toast,
"wns/toast", 2, function(error) {
if (error) {
console.error(error);
}});
}
function
sendTileHubWns(text1, text2, text3, tagExpression)
{
var azure = require("azure");
var notificationHubService =
azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);
var tile = "<tile>" +
"<visual>" +
"<binding
template=\"TileSquareText01\">" +
"<text
id=\"1\">" + text1 + "</text>" +
"<text
id=\"2\">" + text2 + "</text>" +
"<text
id=\"3\">" + text3 + "</text>" +
"</binding>" +
"</visual>" +
"</tile>";
notificationHubService.wns.send(tagExpression, tile,
"wns/tile", 2, function(error) {
if (error) {
console.error(error);
}});
}
function
sendBadgeHubWns(value, tagExpression)
{
var azure = require("azure");
var notificationHubService =
azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);
var badge = "<badge value=\""
+ value + "\" />";
notificationHubService.wns.send(tagExpression, badge,
"wns/badge", 2, function(error) {
if (error) {
console.error(error);
}});
}
These functions can be called like this:
function
sendAllHubNotifications(message)
{
sendToastHubMpns("My Application", message,
null);
sendTileHubMpns("My Application ", message,
null);
sendToastHubWns("My Application ",
"Here’s a notification", message, null);
sendTileHubWns("My Application ",
" Here’s a notification ", message, null;
sendBadgeHubWns("alert", null);
}
Notice there is a tagExpression variable which we have set
to null. We can use this to target notifications at user’s interests which are
registered in the app:
function
sendAllHubNotifications(message)
{
sendToastHubWns("My Application ",
"Here’s a notification", message, "NEWS");
sendTileHubWns("My Application ",
" Here’s a notification ", message, "NEWS");
sendBadgeHubWns("alert", "NEWS");
}
I managed to get Windows 8 to work with this but not Windows
Phone 8
Registering with the Hub from a Windows 8 App
This example shows how to register a Windows 8 Store App
with the DefaultListenSharedAccessSignature connection string this time (from
the Notifocations Hub Dashboard). This registers two tags, but you can use null
to receive everything:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using System.Text;
using
System.Threading.Tasks;
using
Microsoft.WindowsAzure.MobileServices;
using
Newtonsoft.Json.Linq;
using
Microsoft.WindowsAzure.Messaging;
namespace
MyApp
{
internal class MyAppPush
{
private const string HUB_NAME = "myapp";
private const string CONNECTION_STRING
= "Endpoint=sb://myapp.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=/XXXXXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=";
public async static void
UploadChannel()
{
var channel = await
Windows.Networking.PushNotifications.PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
var token =
Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null);
string installationId =
Windows.Security.Cryptography.CryptographicBuffer.EncodeToBase64String(token.Id);
try
{
// Register with hub
var hub = new
NotificationHub(HUB_NAME, CONNECTION_STRING);
var result = await
hub.RegisterNativeAsync(channel.Uri, new string[] { "NEWS", "SUPPORT"
});
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
}
}
Windows Phone 8 apps are registered in the same way, but
they have a slightly different mechanism as they have an event when the URI
changes which needs to be used for registration.