Sending Notifications

0
166

When a survey creator saves a new survey, the Surveys service in Windows Azure retrieves all the URIs for the subscribed Windows Phone 7 devices and then sends the notifications to all the devices that subscribe to notifications for surveys created by that particular survey creator.

The following code example from the NewSurveyNotification Command class in the TailSpin.Workers.Notifications project shows how the Windows Azure worker role retrieves the list of subscribed phones and sends the notifications. This method uses the filtering service to retrieve the list of devices that should receive notifications about a particular survey.

C#
public void Run(NewSurveyMessage message)
{
var survey = this.surveyStore.GetSurveyByTenantAndSlugName(
message.Tenant, message.SlugName, false);
if (survey != null)
{
var deviceUris =
from user in this.filteringService.GetUsersForSurvey(survey)
from deviceUri in this.userDeviceStore.GetDevices(user)
select deviceUri;
foreach (var deviceUri in deviceUris)
{
this.pushNotification.PushTileNotification(
deviceUri.ToString(),
“New Surveys”,
null,
0,
uri => this.userDeviceStore.RemoveUserDevice(new
Uri(uri)));
}
}
}

The Run method also passes a reference to a callback method that removes from the device store phones that are no longer registered with the MPNS.

Note: For more information about how the Run method is triggered, and about retry policies if the Run method throws an exception, Multi-Tenant Application for Windows Azure,” of the book, Developing Applications for the Cloud on the Microsoft Windows Azure™ Platform. This is available on MSDN (http://msdn.microsoft.com/en-us/library/ff966499.aspx).

The following code example shows the PushTileNotification method in the PushNotification class that’s invoked by the worker role command to send the notification. This method creates the tile notification message to send to the MPNS before it calls the Send Message method.

C#
public void PushTileNotification(string channelUri,
string message, string backgroundImage, int count,
DeviceNotFoundInMpns callback)
{
byte[] payload = TileNotificationPayloadBuilder.Create(
message, backgroundImage, count);
string messageId = Guid.NewGuid().ToString();
this.SendMessage(NotificationType.Tile, channelUri, messageId,
payload, callback);
}

The SendMessage method sends messages to the MPNS for forwarding on to the subscribed devices. The following code example shows how the SendMessage method sends the message to the MPNS; the next code example shows how the SendMessage method receives a response from the MPNS.

C#
private void SendMessage(NotificationType notificationType,
string channelUri, string messageId, byte[] payload,
DeviceNotFoundInMpns callback)
{
try
{
WebRequest request = WebRequestFactory.CreatePhoneRequest(
channelUri, payload.Length, notificationType, messageId);
request.BeginGetRequestStream(
ar =>
{
// After the async call returns, get the Stream object.
Stream requestStream = request.EndGetRequestStream(ar);
// Start to write the payload to the stream
// asynchronously.
requestStream.BeginWrite(
payload,
0,
payload.Length,
iar =>
{
// After the writing completes, close the stream.
requestStream.EndWrite(iar);
requestStream.Close();
// Switch to receiving the response from MPNS.

},
null);
},
null);
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
this.OnNotified(notificationType,
(HttpWebResponse)ex.Response);
}
Trace.TraceError(ex.TraceInformation());
}
}

After the SendMessage method sends the message to the MPNS, it waits for a response. It must receive the message asynchronously because the MPNS does not return a response until it, in turn, receives a response from the Windows Phone 7 device. The SendMessage method notifies its caller of the response through the OnNotified method call.

C#

// Switch to receiving the response from MPNS.
request.BeginGetResponse(
iarr =>
{
try
{
using (WebResponse response =
request.EndGetResponse(iarr))
{
// Notify the caller with the MPNS results.
this.OnNotified(notificationType,
(HttpWebResponse)response);
}
}
catch (WebException ex)
{
if (ex.Status ==
WebExceptionStatus.ProtocolError)
{
this.OnNotified(notificationType,
(HttpWebResponse)ex.Response);
}
if (((HttpWebResponse)ex.Response).StatusCode
== HttpStatusCode.NotFound)
{
callback(channelUri);
}
Trace.TraceError(ex.TraceInformation());
}
},
null);

protected void OnNotified(NotificationType notificationType,
HttpWebResponse response)
{
var args = new NotificationArgs(notificationType, response);

}

If the SendMessage method receives a “404 Not Found” response code from the MPNS, it removes the stored subscription details from the store because this response indicates that the device is no longer registered with the MPNS.

The following table summarizes the information available from the MPNS in the response.

MPNS

For more information about sending push notifications, see “How to: Send a Push Notification from a Web Service for Windows Phone” on MSDN (http://msdn.microsoft.com/en-us/library/ff402545(VS.92).aspx).