您的位置:首页 > 其它

Windows Phone 7 不温不火学习之《推送通知服务》

2011-03-05 22:59 381 查看
 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 的事件为如下:

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)
{
//e.ChannelUri 注册的推送通道服务web地址
Debug.WriteLine("CahnnelUri:{0}",e.ChannelUri);
Dispatcher.BeginInvoke(() =>
{
linkButton.IsEnabled = false;
});
}
}
}



之后,我们新建一个Windows Form 应用程序,做为Cloud server 。

  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);
}
}



运行效果如下所示:

APP不运行状态下的TOAST效果如下所示



APP运行状态下的TOAST效果如下所示



运行状态下的RAW推送效果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: