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.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); //打开连接 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 Dispatcher.BeginInvoke(() => { 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.ContentType = "text/xml; charset=utf-8"; sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "token"); sendNotificationRequest.Headers.Add("X-NotificationClass", "1"); // Possible batching interval values: // 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) { // Sets toast notification sendNotificationRequest.ContentType = "text/xml; charset=utf-8"; sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast"); sendNotificationRequest.Headers.Add("X-NotificationClass", "2"); // Possible batching interval values: // 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 运行效果
源码下载:
转自:http://www.oschina.net/question/195301_35388
来源:https://www.cnblogs.com/MessageDream/archive/2012/05/03/2479926.html