最近想给应用添加推送消息,主要是toast消息,所以就打算去了解一下wp消息推送机制以及实现方法,过程中,查了许多资料,也遇到过一些问题,做完后,自己就做个小笔记,总结一下,好记性不如烂笔头嘛,以后可以回头看看,也方便多了,废话不多说!

wp消息推送机制

用一幅图说明,因为官方是英文的,自己在上面添加了一些中文的解析上去,方便大家去理解!

这幅图的核心内容是,当你的应用请求手机Uri(注意:这里uri相当于一个ip或者一个物理地址,是唯一性的一个标识),手机的客户端服务会与微软推送中心联系,然后返回一个uri给客户端推送服务,然后客户端服务再把这个uri给你的应用,你的应用再把这个uri发回来给你的服务器,然后你的服务器再把这个uri和需要发送的消息发送给微软推送中心,最后微软推送中心再根据这个uri,把消息推送到指定的手机!

toast消息推送(wp端)

这个我不想多解释,直接上推送代码,下面的代码主要是查看在应用程序的早期实例中是否已设置 Toast 通知通道。如果找到通知通道,则通知通道连接到通知事件。如果未找到通知通道,则创建通知通道,然后将其连接到通知事件

 // 构造函数
public MainPage()
{
HttpNotificationChannel myChannel = null;
// 推送信道的名字,随便取一个就行了
string ChannelName = "ToastChannel";
InitializeComponent();
// Find静态方法可以根据名字查找信道
myChannel = HttpNotificationChannel.Find(ChannelName);
// 因为系统有时候会删除通道,所以要判断是否存在,如果找不到,就要创建一个了
if (myChannel == null)
{
myChannel = new HttpNotificationChannel(ChannelName);
// 注册事件
myChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(myChannel_ChannelUriUpdated);
myChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(myChannel_ErrorOccurred);
myChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(myChannel_ShellToastNotificationReceived);
// 打开信道
myChannel.Open();
// 绑定Toast通知,这样在程序不在前台时才会显示
// 屏幕上方的通知提示条
myChannel.BindToShellToast();
}
else
{
// 如果存在,还要注册一次事件,因为在程序被扔到后台后可能会删除事件绑定
myChannel.ChannelUriUpdated+=new EventHandler<NotificationChannelUriEventArgs>(myChannel_ChannelUriUpdated);
myChannel.ErrorOccurred+=new EventHandler<NotificationChannelErrorEventArgs>(myChannel_ErrorOccurred);
myChannel.ShellToastNotificationReceived+=new EventHandler<NotificationEventArgs>(myChannel_ShellToastNotificationReceived); // 在“输出”窗输出URL,因为我们只是测试,这样一来方便一点
System.Diagnostics.Debug.WriteLine("通道URI为:{0}", myChannel.ChannelUri.ToString());
}
} void myChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
{
//这里主要是当用户正在使用你的应用,而你刚好推送消息过来,执行此方法
string msg = "";
foreach (string key in e.Collection.Keys)
{
msg += key + " : " + e.Collection[key] + "\r\n";
}
Dispatcher.BeginInvoke(() =>
{
this.txtInfo.Text = msg;
});
} void myChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
{
Dispatcher.BeginInvoke(() => MessageBox.Show(e.Message)); //错误产生的时候,执行这里面内容,实际情况,可以根据 自己需要处理
} void myChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
// 当URL发生改变后,还要输出一次
// 保证我们得到的是最新版本的URI
Dispatcher.BeginInvoke(() =>
{
System.Diagnostics.Debug.WriteLine("通道URI:{0}", e.ChannelUri.ToString());
});
}

toast消息推送(server端)

这里我创建一个 ASP.NET 网页,该网页使用在设备上创建推送通道时返回的 URI 来发送 Toast 通知,当然你可以使用任何能发送网络消息的应用来推送,如winform jsp  php等等

具体推送消息代码如下:

    private void SendMsg()
{
//txtUrl.Tex该参数是手机的uri,要推送消息,首先要确定你要推送用户手机的uri
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(txtUrl.Text);
myRequest.ContentType = "text/xml";
myRequest.Headers.Add("X-WindowsPhone-Target", "toast");
/*
* X-NotificationClass 处理间隔
* 2 - 立即发送
* 12 - 450秒内发送
* 22 - 900秒内发送
*/
myRequest.Headers.Add("X-NotificationClass", ""); // 要发送的内容 txtValue1.Text:标题,txtValue2.Text:推送内容,txtParam.Text:当用户点击消息的时候,导航的页面,如mainpage.xaml
string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Toast>" +
"<wp:Text1>" + txtValue1.Text + "</wp:Text1>" +
"<wp:Text2>" + txtValue2.Text + "</wp:Text2>" +
"<wp:Param>" + txtParam.Text + "</wp:Param>" +
"</wp:Toast>" +
"</wp:Notification>"; byte[] buffer = Encoding.UTF8.GetBytes(toastMessage);//注意此处官方是Encoding.default.GetBytes(toastMessage),我在使用的过程中,老是报错,下面会说原因 myRequest.ContentLength = buffer.Length;
myRequest.Method = "POST"; using (Stream stream = myRequest.GetRequestStream())
{
stream.Write(buffer, , buffer.Length);
} // 发送消息和获取回应
HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"]; //判断是否成功推送到微软推送服务中心
// TextBoxResponse.Text = notificationStatus + " | " + deviceConnectionStatus + " | " + notificationChannelStatus;
if (notificationStatus == "Received" && deviceConnectionStatus == "Connected" && notificationChannelStatus == "Active")
{
success++;
}
}

总结和注意

(1)  其中<wp:Param>" + txtParam.Text + "</wp:Param>,当param内容为空时,可以省略不写这一节点。同时,在xml中一些字符是要进行转换的:

<Text1> 和 <Text2> 都采用字符串格式。

<Param> 值允许以下格式:

  • /page1.xaml – 定义应用程序启动时导航到的应用程序中的页面。该页面必须以“/”开头。

  • /page1.xaml?value1=1234 &amp;value2=9876 – 定义应用程序启动时导航到的页面,以及信息的名称/值对。该页面必须以“/”开头。

  • ?value1=1234 &amp;value2=9876 – 包含传递给应用程序默认开始页面的信息名称/值对。该页面必须以“?”开头。

字符

XML 编码

<

&lt;

>

&gt;

&

&amp;

&apos;

&quot;

(2)  当服务端发送的toast通知中有xml格式错误或者非法内容时,微软推送服务会关闭此通道,并提示出错。我在运行时老是报错(“The XML payload contains invalid or improperly formatted XML or the notification type specified in the header does not match the payload type used.  The channel has been closed.  Check your XML payload for errors and reopen the channel to obtain a new URI.”)。      
经过查资料,我把里面的Encoding.default.GetBytes(toastMessage)改为Encoding.UTF8.GetBytes(toastMessage),这样就把不报错了,此处可能是官方示例代码有些问题。
 
(3)  我们Server端想统计推送的成败情况的话,会比较困难。因为从微软推送服务中返回的相应代码中,只是简单的反映了推送通知到达代理服务器的情况,而非通知到达客户端时的结果。比如微软的代理服务器返回了响应码200,我们Server端只是知道了信息已经成功到达了它那里,并且符合转发到客户端程序的条件;至于客户端最终是否真的收到了通知,无法从这里获知。当然,当客户端程序接收到了通知后,可以向Server端汇报,但这并不准确,因为有些信息可能因为程序不在前台运行同时又被用户忽略了,此处我直接以三个信息头X-NotificationStatus  X-SubscriptionStatus  X-DeviceConnectionStatus来判断是否成功发到微软的推送中心来判断是否发送成功,至于有其他更准确方案,知道的话,请告诉我!

wp推送消息笔记的更多相关文章

  1. Windows phone Toast消息推送 学习笔记

    简单介绍: Windows phone平台支持三种形式的推送通知: 1.Tile——也就是在Start屏幕程序平铺图标 2.Toast——创建一个显示在当前屏幕中的Toast弹出窗口 3.Raw——有 ...

  2. 使用PushSharp给iOS应用推送消息

    PushSharp是一个C#编写的服务端类库,用于推送消息到各种客户端,支持iOS(iPhone/iPad).Android.Windows Phone.Windows 8.Amazo.Blackbe ...

  3. Java端百度云推送消息Demo

    因为在做Java服务器有用到推送消息机制,于是到网上找了一下,就自己试着敲了一个demo.这个demo主要是简单的一个对app消息推送. jar:百度云消息推送Java端的jar. package x ...

  4. android不需要Socket的跨进程推送消息AIDL!

    上篇介绍了跨进程实时通讯http://www.cnblogs.com/xiaoxiaing/p/5818161.html 但是他有个缺点就是服务端无法推送消息给客户端,今天这篇文章主要说的就是服务器推 ...

  5. 使用极光推送(www.jpush.cn)向安卓手机推送消息【服务端向客户端主送推送】C#语言

    在VisualStudio2010中新建网站JPushAndroid.添加引用json帮助类库Newtonsoft.Json.dll. 在web.config增加appkey和mastersecret ...

  6. 用JPUSH极光推送实现服务端向安装了APP应用的手机推送消息(C#服务端接口)

    这次公司要我们做一个功能,就是当用户成功注册以后,他登录以后要收到消息,当然这个消息是安装了我们的手机APP应用的手机咯. 极光推送的网站的网址是:https://www.jpush.cn/ 极光推送 ...

  7. iOS点击推送消息跳到应用指定页面

    现在的推送用的越来越频繁,几乎每个应用都开始用到了.其实又有几个用户会去看推送消息呢?没办法,产品经理最大啊,只是苦了我们这一帮程序员啊!闲话少说,进入正题.兄弟我用的是极光推送,自然是以极光推送为例 ...

  8. signalr推送消息

    参考:Tutorial: Getting Started with SignalR 2 and MVC 5 环境:vs2013,webapi2,entity framework6.0 实现效果:当用户 ...

  9. DWR实现后台推送消息到web页面

    DWR简介 DWR(Direct Web Remoting)可用于实现javascript直接调用java函数和后台直接调用页面javascript代码,后者可用作服务端推送消息到Web前端. (服务 ...

随机推荐

  1. python早期看书笔记

  2. 36、NSTimer使用详解-开启、关闭、移除

    1.要是用一个定时器,首先要定义一个定时器: @property(strong,nonatomic)NSTimer *myTimer;//定时器 2.初始化,初始化有两种方式: 第一种: + (NST ...

  3. docker 批量操作容器

    docker stop $(sudo docker ps -q)

  4. latex去掉页眉

    \begin{document}之前添加 \fancyhead{} 即: \fancyhead{} \begin{document}

  5. C语言三种方法调用数组

    #include <stdio.h> /********************************* * 方法1: 第一维的长度可以不指定 * * 但必须指定第二维的长度 * *** ...

  6. AngularJS监听数组变化

    我们在使用angualr的监听时候,业务的需要我们会去监听一个数组的某一个值得变化,再写逻辑代码.然而我们在使用$scope.$watch("",function(){ })时候会 ...

  7. 20169207《linux内核原理与分析》第二周作业

    第一部分:学习MOOC网Linux内核分析的课程. 首先对冯诺依曼体系结构和存储程序计算机工作模型进行了了解,查阅资料,对冯诺依曼体系的特点与课堂上的相结合,真实明白了模型的特点. 在汇编C语言程序时 ...

  8. SSM_CRUD新手练习(5)测试mapper

    上一篇我们使用逆向工程生成了所需要的bean.dao和对应的mapper.xml文件,并且修改好了我们需要的数据库查询方法. 现在我们来测试一下DAO层,在test包下新建一个MapperTest.j ...

  9. Mac使用终端安装Homebrew(brew)

    Homebrew简称brew,OSX上的软件包管理工具,在Mac终端可以通过brew安装.更新.卸载软件. 1.打开终端直接输入下面指令回车: // ruby -e "$(curl -fsS ...

  10. kettle学习

    数据etl工具,主要用做数据采集和清洗 待续...