This post is a preview of the Recipe for the Push Notification Server Side Helper Library. The library provides an easy way for sending all three kinds of push notification messages currently supported by Microsoft Push Notification Services (MPNS): Tile, Toast, and Raw. Our main goal here is to extract any complexity for sending push notification (PN) messages from your website (or web service) to a Windows Phone. This library helps developers to send push messages using only a few lines of code.
We are not going to cover what push notifications are, or how they work. If you are not familiar with push notifications please be sure to read the previous posts: Understanding Microsoft Push Notifications for Windows Phones part 1 andpart 2, as well as Using Push Notification from Your Windows Phone Application, or refer to the Push Notificationsdocumentation on MSDN.
In a push notification scenario, the server side piece is as important as the Windows Phone client application. For a complete end-to-end push-enabled scenario to work, you need your server side to be able to receive incoming phone messages, as well as send push requests to Microsoft Push Notification Services as illustrated in the following diagram
As we said before, the Push Notification Server Side Helper Library helps you send push notification requests from your cloud application (web service) to MPNS, and manage (understand) the return values received from MPNS in response.
This post provides some background and an example of what you will find in greater detail in the Recipe. To start with, the recipe includes four projects, from which the library is the WindowsPhone.Recipes.Push.Messages assembly. The projects are:
Since we are using WCF service to open a channel for incoming communications, you need to run the entire Visual Studio solution in “Admin mode” or else you will hit an exception when you try to run the WPF “server” application. But before we jump ahead, let’s understand how to use the helper library
In order to send a PN message to your Windows Phone application, you need to post that message to MPNS. Therefore, it makes sense to abstract the sending functionality and create a PushNotificationMessage base class. This base class handles the majority of the logic and heavy lifting for sending the message to MPNS.
The main public functions that the PushNotificationMessage base class exposes are two send methods:
Both methods have a callback for returning the MPNS response codes, and can throw an exception if something goes wrong. A separate sub-class represents each of the different PN message types, as illustrated in the following class diagram.
The three supported PN message sub-classes are:
The difference between the three types of messages is the way each one encapsulates the push message format and exposes it with regular .NET properties. Using any of these classes to send a message is relatively easy as shown in the following code samples".
var tile = new TilePushNotificationMessage
{
BackgroundImageUri = tileImageUri, // Remote or phone-local tile image uri.
Count = tileCount, // Counter between 1 to 99 should be displayed on the tile.
Title = “Tile Title” // Title to be displayed on the tile.
};
// Send the message synchronously.
Var sendResult = tile.Send(phoneChannelUri);
// Send the message asynchronously.
tile.SendAsync(
phoneChannelUri,
result => {/* Check the send result */},
exception => {/* Log the error */});
When sending asynchronously, you need to provide delegates as callback handlers for the return values from MPNS and to log any exceptions.
Similarly, you can send toast and raw notifications, by simply instantiating new instances of ToastPushNotificationMessageand RawPushNotificationMessage, respectively.
To illustrate the use of the Push Notification Server Side Helper Library, we’ve create a WPF application that acts like a web service, mimicking a third-party server. To enable this, the WPF application has a WCF service that lets the Windows Phone application register and communicate with MPNS. The WPF has tabs, each of which represents a specific Push Pattern that we wish to illustrate.
Push Patterns are a generalization of a common use of PN in an end-to-end solution that includes specific Windows Phone and server-side logic. The current application has five patterns:
Please note: The server-side patterns are provided as a samples and only to demonstrate the specific pattern usage; they are NOT best practices for server-side or web programming. The goal is to explain the patterns and server-side requirements. To keep the examples simple, we DO NOT use server-side authentication, a database, or any complex setups that would be included in actual scenarios.
As an example, let’s examine the Ask to Pin Application Tile scenario as it explained in the Recipe.
If a given application sends a tile PN message and that application’s tile is not pinned to the phone Start screen, the PN message will not be delivered to the phone, and the third-party server side will be notified that the application tile is not pinned. Since in Windows Phone, only end users can pin an application’s tile to the phone Start Screen, applications need a way to “ask” the user to pin the application’s tile. This pattern illustrates how an application can do that by sending a specific message to the phone. The pattern implementation includes both server-side and Windows Phone client-side code.
Demonstration
Note –This pattern can be adjusted to make the Windows Phone client application display the “Ask to Pin” message upon logon.
Code [Implemented as part of the AskToPinPushPatternViewModel.cs file in the WPF application]
The pattern starts when a client first registers to the server. In order to check if the application is pinned or not, theOnSubscribed method below sends a tile notification message to the relevant subscriber (based on the Windows Phone client application URI and username). The data used with the message is new for first time subscriptions or from previously stored data for re-subscriptions. Using stored data prevents updating the tile for no reason.
protected override void OnSubscribed(SubscriptionEventArgs args)
{
// Asynchronously try to send Tile message to the relevant subscriber
// with data already sent before so the tile won't change.
var tileMsg = GetOrCreateMessage(args.Subscription.UserName, false);
tileMsg.SendAsync(
args.Subscription.ChannelUri,
result =>
{
Log(result);
OnMessageSent(args.Subscription.UserName, result);
},
Log);
}
The PN message is sent asynchronously, and the OnMessageSent callback is called when the tile PN message is sent. At that point, the server side can check if the application is pinned to the Start screen by checking the response returned by MPNS. If the tile is pinned, do nothing. However, if the application’s tile is not pinned, the Windows Phone client application will “ask” the user to pin the application’s tile by sending a raw message with custom data, in our case the “Ask to Pin” message. This raw message is received by the phone client and displays a message to the user.
/// <summary>
/// Once tile update sent, check if handled by the phone.
/// In case that the application is not pinned, ask to pin.
/// </summary>
private void OnMessageSent(string userName, MessageSendResult result)
{
if (!CheckIfPinned(result))
{
AskUserToPin(result.ChannelUri);
}
}
The same logic repeats in cases where the server wants to send a tile update to one or more clients. This time the message is newly created.
/// <summary>
/// Send a tile notification to all relevant subscribers.
/// </summary>
protected override void OnSend()
{
// Asynchronously try to send this message to all relevant subscribers.
foreach (var subscriber in PushService.Subscribers)
{
// Create a tile message to send an update.
var tileMsg = GetOrCreateMessage(subscriber.UserName);
tileMsg.SendAsync(
subscriber.ChannelUri,
result =>
{
Log(result);
OnMessageSent(subscriber.UserName, result);
},
Log);
}
}
The CheckIfPinned method below checks if the application is pinned to the Start screen by observing the three previously described flags.
private bool CheckIfPinned(MessageSendResult result)
{
// We known if the application is pinned by checking the following send result flags:
return result.DeviceConnectionStatus == DeviceConnectionStatus.Connected &&
result.SubscriptionStatus == SubscriptionStatus.Active &&
result.NotificationStatus == NotificationStatus.Received;
}
The AskUserToPin method below sends a raw message with the custom “Ask to Pin” data, which is intercepted by the phone.
/// <summary>
/// Just in case that the application is running, send a raw message, asking
/// the user to pin the application. This raw message has to be handled in client side.
/// </summary>
private void AskUserToPin(Uri uri)
{
new RawPushNotificationMessage
{
RawData = Encoding.ASCII.GetBytes(RawMessage)
}.SendAsync(uri);
}
Conclusion
The Push Notification Server Side Helper Library is a simple library that lets you focus on your web service logic rather than on the technicality of sending push messages.
The actual Recipe contains detailed documentation and full code implementation. The above example is just one of 5 scenarios, each with full details.
Download the Recipe and its documentation