最近想给应用添加推送消息,主要是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. java测试ATM自助操作系统

    开学第一周系主任安排了一项测试,测试要求:模拟ATM自助取款机用文件进行存储账户信息,密码等,并进行存款取款,转账,查询记录等操作,而且要进行文件的读取与录入. 这是一个ATM自助取款的操作系统,进行 ...

  2. kbmmw 中JSON 操作入门

    现在各种系统中JSON 用的越来越多.delphi 也自身支持JSON 处理. 今天简要说一下kbmmw 内部如何使用和操作JSON. kbmmw 中json的操作是以TkbmMWJSONStream ...

  3. Oracle导入的常见语句

    登录sql > sqlplus / as sysdba 创建表空间sql > create tablespace TABLESPACE datafile 'e:\tables1.dbf' ...

  4. 2019.02.09 bzoj2560: 串珠子(状压dp+简单容斥)

    传送门 题意简述:nnn个点的带边权无向图,定义一个图的权值是所有边的积,问所有nnn个点都连通的子图的权值之和. 思路: fif_ifi​表示保证集合iii中所有点都连通其余点随意的方案数. gig ...

  5. 2019.02.09 bzoj4455: [Zjoi2016]小星星(容斥原理+dp)

    传送门 题意简述:给一张图和一棵树(点数都为n≤17n \le17n≤17),问有多少种给树的标号方法方法使得图中去掉多余的边之后和树一模一样. 思路: 容斥好题啊. 考虑fi,jf_{i,j}fi, ...

  6. 2019.01.24 NOIP训练 旅行(轮廓线dp)

    传送门 题意简述: 给一个n∗mn*mn∗m的有障碍的网格图,问你从左上角走到左下角并覆盖所有可行格子的路径条数. 思路: 路径不是很好算. 将图改造一下,在最前面添两列,第一列全部能通过,第二列只有 ...

  7. 2018.11.18 spoj Triple Sums(容斥原理+fft)

    传送门 这次fftfftfft乱搞居然没有被卡常? 题目简述:给你nnn个数,每三个数ai,aj,ak(i<j<k)a_i,a_j,a_k(i<j<k)ai​,aj​,ak​( ...

  8. $.cookie is not a function的错误原因

    网上说的原因是:“手残导入2次jquery库文件 ” 是的,就是这个原因.引入了两次jquery.js

  9. java 冒泡排序 二分查找 选择排序 插入排序

    下面这个程序是先定义一个整型数组,然后将其中的元素反序赋值,再用冒泡排序进行排序以后用二分查找来查找其中是否有某个数,返回值为-1时表示这个数可能小于这个数组的最小值或大小这个数组的最大值,-2表示这 ...

  10. 5.Vue临时上传文件夹

    1.在项目目录中,通过npm install multiparty进行安装必要组件npm install multiparty --save-dev 2.app.js中添加app.use(bodyPa ...