最近想给应用添加推送消息,主要是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. [转]MySQL索引原理及慢查询优化

    MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位 ...

  2. Jquery 的ajax里边不能识别$(this)

    确实不能用,在ajax外面弄个变量$this= $(this),然后在里面用就行了 在jQuery使用ajax后$(this)失效,原因很简单,$(this)指向的是最近调用它的jquery对象,即$ ...

  3. openstack查看命令的restful调用形式

    [root@cc10 fast-pulsar2]# [root@cc10 fast-pulsar2]# cinder --debug type-create hzb DEBUG:keystonecli ...

  4. c#用EPPLUS操作excel

    参考: http://www.cnblogs.com/rumeng/p/3785748.html http://www.cnblogs.com/libla/p/5824296.html#3818995 ...

  5. HDU 5663 Hillan and the girl (莫比乌斯反演 + 分块)

    题意:给定n,m,求,其中F(x)=0,,如果x是完全平方数,否则是1. 析: 由于按照题意的F,不好筛选,所以我们反过来,F(x),x是平方数,就是1,否则是0. 这个是可以预处理出来的,可以用筛选 ...

  6. java web 实现文件夹上传(保留目录结构)

    今天我弄了一下文件夹上传(很简单的 首先,我们的html需要这样写 <form action="/file/upload" enctype="multipart/f ...

  7. 属性动画和Activity、Fragment过渡动画等

    主题是关于动画的,但是不是什么动画的内容都包括.先泛泛的介绍一下,然后详细的介绍一下翻代码找见的一个好玩的动画的使用.以下的内容包括Android 3和Android 3.1等引入的API,在使用中请 ...

  8. (最大上升子序列)Monkey and Banana -- hdu -- 1069

    http://acm.hdu.edu.cn/showproblem.php?pid=1069      Monkey and Banana Time Limit:1000MS     Memory L ...

  9. bash多进程

    #!/bin/bashCMD_PATH=`dirname $0`#echo $CMD_PATH > /home/wubin/testjava -jar $CMD_PATH/Server.jar ...

  10. spring-mvc源码阅读笔记

    简要的做一些spring-mvc部分的源码学习笔记 Spring-mvc做的工作主要是俩大方面吧:一个是初始化一个ioc容器,一个是mvc部分的控制和视图模块的实现. 先说下ioc容器的初始化部分:i ...