Windows Phone 中的 Microsoft Push Notification Service 向第三方開發人員提供了一個彈性,專注,而且持續的管道,使得開發人員可以從Web Service 向移動應用程式發送資訊和更新。
過去移動應用程式需要經常主動通路相應的WEB服務,以了解是否有任何等待處理的通知。這樣做是有效的,但會導航手機無線裝置頻繁打開,進而對電池續航時間或者使用者的流量帶來負面 影響。使用推送通知的方式取代主動調查,Web Service 能夠提醒應用程式擷取所需要的重要理更新。
當一個Web Service 有資訊要發送到應用程式,它先發送一個通知到Push Notification Service ,該服務随後将通知應用程式,應用程式的标題明顯地更新或者顯示一個Toast 通知。然後,如果需要的話,應用程式可以使用自己的的協定聯系Web service 以擷取更新。
關于推送通知服務,看了Jake Lin 的視訊他說的“好萊塢原則”己經說得很清楚了,不過我自己從現實中的淘寶購物也産生了一定的了解,下面跟大家分享一下,給出圖示:
如上圖,我們可以把推送通知了解成,一部手機就相當于我們一個使用者,在淘寶注冊了帳号并填寫了送貨位址(URI),在購買完自己需要的物品後,通知淘寶商家發貨了,這時淘寶商家接收到我們給出的URI,就把貨品打包,可以使用萬能打包把什麼東西都放進去(Raw)或者根據我們的要求要打包成禮品的樣子(Tokens或者Toast 需要的XML格式 ),之後通知快遞公司(微軟--》不同的是,微軟是免費的幫我們快遞 ) 。而當我們收到快遞公司給予我們的通知後,如打電話說:“先生,你的貨品己經到達,請接收”,之後我們就根據打包方式進行接收啦。
大意的了解是這樣的。
Push notification 發送方式
如上一段文字出現了幾個英文單詞就是Push notification 的三種發送方式,分别為:
-
Raw Notification
1.可以發送任何格式的資料
2.應用程式可以根據需要加工資料
3.應用程式相關(application-specific)通知消息
4.隻有在應用程式運作時,才發送。
-
Toast Notification
1.發送的資料為指定的XML 格式
2.如果應用程式正在運作,内容發送到應用程式中
3.如果應用程式沒有運作,彈出Toast 消息框顯示消息
3.1App 圖示加上兩個描述文本
3.2打斷使用者目前操作,但是是臨時的
3.3使用者可以點選進行跟蹤
-
Tokens (Tile) Notification
1.發送的資料為指定的XML格式
2.不會往應用程式進行發送
3.如果使用者把應用程式PIN TO START ,那麼更新資料發送到start screen 的tile 裡面
3.1包含三個屬性,背景,标題和電腦
3.2每個屬性都有固定的格式與位置
3.3可以使用其中的屬性,不一定三個屬性一起使用
Push Notification使用規範
- 目前版本的Windows Phone 隻支援最多15 個第三方應用程式使用推送服務通知服務
- 應用程式必須内置詢問使用者是否使用推送通知服務的功能
- 應用程式必須内置使用者可以取消推送通知服務的功能
Demo 示範
關于Push Notification 的事件為如下:
//注冊URI
httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(httpChannel_ChannelUriUpdated);
//發生錯誤的事件
httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(httpChannel_ErrorOccurred);
//Raw 推送通知服務事件
httpChannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(httpChannel_HttpNotificationReceived);
//toast 推送通知服務事件
httpChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(httpChannel_ShellToastNotificationReceived);
我們可以在需要注冊的地方使用,Windows Phone 的大緻使用代碼為如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
///引用通知服務命名空間
using Microsoft.Phone.Notification;
using System.Diagnostics;
using System.IO;
namespace PushNotificationDemo
{
public partial class MainPage : PhoneApplicationPage
{
private HttpNotificationChannel httpChannel;
private const string channelName = "Channel";
// Constructor
public MainPage()
{
InitializeComponent();
}
private void linkButton_Click(object sender, RoutedEventArgs e)
httpChannel = HttpNotificationChannel.Find(channelName);
//如果存在就删除
if (httpChannel!=null)
{
httpChannel.Close();
httpChannel.Dispose();
}
httpChannel = new HttpNotificationChannel(channelName, "NotificationServer");
//注冊URI
//打開連接配接
httpChannel.Open();
//綁定toast 推送服務
httpChannel.BindToShellToast();
//綁定Tokens (tile) 推送服務
httpChannel.BindToShellTile();
void httpChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
string msg = string.Empty;
foreach (var key in e.Collection.Keys)
msg += key + " : " + e.Collection[key] + Environment.NewLine;
Dispatcher.BeginInvoke(() =>
msgTextBlock.Text = msg;
});
void httpChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e)
//Raw 支援任意格式資料
using (var reader=new StreamReader(e.Notification.Body))
string msg = reader.ReadToEnd();
Dispatcher.BeginInvoke(() =>
{
msgTextBlock.Text = msg;
});
void httpChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
//子線程中更新UI
msgTextBlock.Text = e.Message;
} );
void httpChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
Debug.WriteLine("CahnnelUri:{0}",e.ChannelUri);
Dispatcher.BeginInvoke(() =>
linkButton.IsEnabled = false;
}
}
之後,我們建立一個Windows Form 應用程式,做為Cloud server 。
首先,建立一個枚舉,建立三個枚舉項為如下:
public enum notificationType
raw,
toast,
tokens
然後編寫發送通知服務通用方法體:
void sendNotificationType(byte[] payLoad,notificationType type)
// The URI that the Push Notification Service returns to the Push Client when creating a notification channel.
HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(NotificationUriTextBox.Text);
// HTTP POST is the only allowed method to send the notification.
sendNotificationRequest.Method = WebRequestMethods.Http.Post;
// The optional custom header X-MessageID uniquely identifies a notification message. If it is present, the
// same value is returned in the notification response. It must be a string that contains a UUID.
sendNotificationRequest.Headers["X-MessageID"] = Guid.NewGuid().ToString();
if (type==notificationType.raw)
// Sets raw notification
sendNotificationRequest.ContentType = "text/xml; charset=utf-8";
sendNotificationRequest.Headers.Add("X-NotificationClass", "3");
// Possible batching interval values:
// 3: The message is delivered by the Push Notification Service immediately.
// 13: The message is delivered by the Push Notification Service within 450 seconds.
// 23: The message is delivered by the Push Notification Service within 900 seconds.
else if (type == notificationType.tokens)
// Sets toast notification
sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "token");
sendNotificationRequest.Headers.Add("X-NotificationClass", "1");
// 1: The message is delivered by the Push Notification Service immediately.
// 11: The message is delivered by the Push Notification Service within 450 seconds.
// 21: The message is delivered by the Push Notification Service within 900 seconds.
else if (type==notificationType.toast)
{
sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
sendNotificationRequest.Headers.Add("X-NotificationClass", "2");
// 2: The message is delivered by the Push Notification Service immediately.
// 12: The message is delivered by the Push Notification Service within 450 seconds.
// 22: The message is delivered by the Push Notification Service within 900 seconds.
// Sets the web request content length.
sendNotificationRequest.ContentLength = payLoad.Length;
// Sets the notification payload to send.
byte[] notificationMessage = payLoad;
// Sends the notification.
using (Stream requestStream = sendNotificationRequest.GetRequestStream())
requestStream.Write(notificationMessage, 0, notificationMessage.Length);
// Gets the response.
HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
MsgLabel.Text = String.Format("通知狀态:{0},管道狀态:{1},裝置狀态:{2}",
notificationStatus, notificationChannelStatus, deviceConnectionStatus);
設定點選後,請求微軟做推送服務:
private void button1_Click(object sender, EventArgs e)
string msg = String.Format("{0}{1}, {2}度", LocationComboBox.Text,
WeatherComboBox.Text, TemperatureTextBox.Text);
string type = NotificationTypeComboBox.Text as string;
if (type == "Raw")
byte[] strBytes = new UTF8Encoding().GetBytes(msg);
sendNotificationType(strBytes,notificationType.raw);
else if (type == "Toast")
string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Toast>" +
"<wp:Text1>天氣更新</wp:Text1>" +
"<wp:Text2>" + msg + "</wp:Text2>" +
"</wp:Toast>" +
"</wp:Notification>";
byte[] strBytes = new UTF8Encoding().GetBytes(toastMessage);
sendNotificationType(strBytes,notificationType.toast);
else if (type == "Tile")
string tileMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Tile>" +
"<wp:BackgroundImage>/Images/" + WeatherComboBox.Text + ".png</wp:BackgroundImage>" +
"<wp:Count>" + TemperatureTextBox.Text + "</wp:Count>" +
"<wp:Title>" + LocationComboBox.Text + "</wp:Title>" +
"</wp:Tile> " +
"</wp:Notification>";
byte[] strBytes = new UTF8Encoding().GetBytes(tileMessage);
sendNotificationType(strBytes, notificationType.tokens);
注:本篇URI是通過列印得到。然後指派給Windows Form 應用程式,如下圖:
例子運作效果如下圖:
上圖為Raw notification運作效果
運作時的Toast
不運作時的Taost
Tokens 運作效果
×××: