博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重新想象 Windows 8 Store Apps (67) - 后台任务: 推送通知
阅读量:5903 次
发布时间:2019-06-19

本文共 8823 字,大约阅读时间需要 29 分钟。

原文:

重新想象 Windows 8 Store Apps (67) - 后台任务: 推送通知

作者:
介绍
重新想象 Windows 8 Store Apps 之 后台任务

  • 推送通知

示例
1、客户端
BackgroundTask/PushNotification.xaml

BackgroundTask/PushNotification.xaml.cs

/* * 演示如何接收推送通知 *  * 注: * 需要在 Package.appxmanifest 中增加后台任务声明,并勾选“推送通知” * 在 win8 商店创建了应用后,需要将此 app 的商店中的 identity 复制到 Package.appxmanifest 的 identity 节点 * 不能在模拟器中运行 * 每次新建的 channel 有效期为 30 天 *  * 另: * WNS - Windows Push Notification Service * 推送通知的服务端参见:WebServer/PushNotification 内的文件 */using System;using Windows.ApplicationModel.Background;using Windows.Networking.PushNotifications;using Windows.UI.Notifications;using Windows.UI.Popups;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;namespace XamlDemo.BackgroundTask{    public sealed partial class PushNotification : Page    {        public PushNotification()        {            this.InitializeComponent();        }        private async void btnCreateChannel_Click(object sender, RoutedEventArgs e)        {            // 当收到推送的 raw 通知时,如果 app 在锁屏,则可以触发后台任务以执行相关的逻辑(PushNotificationTrigger)            BackgroundAccessStatus status = BackgroundExecutionManager.GetAccessStatus();            if (status == BackgroundAccessStatus.Unspecified)            {                status = await BackgroundExecutionManager.RequestAccessAsync();            }            if (status == BackgroundAccessStatus.Denied)            {                await new MessageDialog("请先将此 app 添加到锁屏").ShowAsync();                return;            }            // 创建一个推送通知信道,每个新建的 channel 有效期为 30 天,所以建议每次进入 app 后都重新建一个 channel(但是需要注意间隔较短的话,则会复用之前的 channel)            PushNotificationChannel channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();            // 接收到通知后所触发的事件            channel.PushNotificationReceived += channel_PushNotificationReceived;            // channel.Close(); // 关闭 channel            // channel.ExpirationTime; // channel 的过期时间,此时间过后 channel 则失效            // channel 的 uri 地址,服务端通过此 uri 向此 app 推送通知            txtUri.Text = channel.Uri.ToString();        }        void channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args)        {            switch (args.NotificationType)            {                case PushNotificationType.Badge: // badge 通知                    BadgeUpdateManager.CreateBadgeUpdaterForApplication().Update(args.BadgeNotification);                    break;                case PushNotificationType.Raw: // raw 通知                    // 当收到推送的 raw 通知时,如果 app 在锁屏,则可以触发后台任务以执行相关的逻辑(PushNotificationTrigger)                    string msg = args.RawNotification.Content;                    break;                case PushNotificationType.Tile: // tile 通知                    TileUpdateManager.CreateTileUpdaterForApplication().Update(args.TileNotification);                    break;                case PushNotificationType.Toast: // toast 通知                    ToastNotificationManager.CreateToastNotifier().Show(args.ToastNotification);                    break;                default:                    break;            }            args.Cancel = true;                    }    }}

Package.appxmanifest

2、服务端
WebServer/PushNotification/OAuthToken.cs

/* * 用于反序列化从 https://login.live.com/accesstoken.srf 获取到的结果 */using System.Runtime.Serialization;namespace WebServer.PushNotification{    [DataContract]    public class OAuthToken    {        [DataMember(Name = "access_token")]        public string AccessToken { get; set; }        [DataMember(Name = "token_type")]        public string TokenType { get; set; }    }}

WebServer/PushNotification/OAuthHelper.cs

/* * https://login.live.com/accesstoken.srf 的 OAuth 验证的帮助类 */using System;using System.IO;using System.Net;using System.Runtime.Serialization.Json;using System.Text;namespace WebServer.PushNotification{    public class OAuthHelper    {        ///         /// 获取 https://login.live.com/accesstoken.srf 的 OAuth 验证的 access-token        ///         /// 在 win8 商店创建 app 后获取到的 “客户端密钥”        /// 在 win8 商店创建 app 后获取到的 “程序包安全标识符(SID)”        /// 
public OAuthToken GetAccessToken(string secret, string sid) { var urlEncodedSecret = UrlEncode(secret); var urlEncodedSid = UrlEncode(sid); var body = String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", urlEncodedSid, urlEncodedSecret); string response; using (WebClient client = new WebClient()) { client.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); response = client.UploadString("https://login.live.com/accesstoken.srf", body); } return GetOAuthTokenFromJson(response); } private OAuthToken GetOAuthTokenFromJson(string jsonString) { using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString))) { var ser = new DataContractJsonSerializer(typeof(OAuthToken)); var oAuthToken = (OAuthToken)ser.ReadObject(ms); return oAuthToken; } } private static string UrlEncode(string str) { StringBuilder sb = new StringBuilder(); byte[] byStr = System.Text.Encoding.UTF8.GetBytes(str); for (int i = 0; i < byStr.Length; i++) { sb.Append(@"%" + Convert.ToString(byStr[i], 16)); } return (sb.ToString()); } }}

WebServer/PushNotification/Push.aspx.cs

/* * 演示如何向 app 推送通知 *  * 注: * 关于推送通知服务请求和响应头的详细说明参见:http://msdn.microsoft.com/zh-cn/library/windows/apps/hh465435.aspx */using System;using System.IO;using System.Net;using System.Text;namespace WebServer.PushNotification{    public partial class Push : System.Web.UI.Page    {        protected void Page_Load(object sender, EventArgs e)        {            // 向某个 app 推送通知的 channel 地址            string notifyUrl = "https://sin.notify.windows.com/?token=AgYAAABQnraWSMQXRveiofxSXGKMHaPB84FLMhFa3D6TQZRHzRSPeByl%2f1O%2frPAcc3ipjpT2cQXfivh589zEV8AOYkR%2fLwXoT2esZnC3hS%2fN7q94ZzJFLnpQsDsYNolFiEAhbHQ%3d";            // 在 win8 商店创建 app 后获取到的 “程序包安全标识符(SID)”            string sid = "ms-app://s-1-15-2-1530173461-470787880-3155417234-2904423500-2475821181-4070965884-3773336209";            // 在 win8 商店创建 app 后获取到的 “客户端密钥”            string secret = "bs08Acs1RG7jB7pkGVMh8EmGKCG3pH+3";            OAuthHelper oAuth = new OAuthHelper();            OAuthToken token = oAuth.GetAccessToken(secret, sid);            try            {                HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(notifyUrl);                // toast, tile, badge 为 text/xml; raw 为 application/octet-stream                myRequest.ContentType = "text/xml";                // 推送消息的类型:wns/toast | wns/badge | wns/tile | wns/raw                myRequest.Headers.Add("X-WNS-Type", "wns/toast");                // 设置 access-token                myRequest.Headers.Add("Authorization", String.Format("Bearer {0}", token.AccessToken));                // 注:app 通过 toast 激活后可以通过 OnLaunched() 中的 args.Arguments 来获取此处 launch 指定的值                string toastMessage = "
推送通知:" + DateTime.Now.ToString("mm:ss") + "
"; byte[] buffer = Encoding.UTF8.GetBytes(toastMessage); myRequest.ContentLength = buffer.Length; myRequest.Method = "POST"; using (Stream stream = myRequest.GetRequestStream()) { stream.Write(buffer, 0, buffer.Length); } using (HttpWebResponse webResponse = (HttpWebResponse)myRequest.GetResponse()) { /* * 响应代码说明 * 200 - OK,WNS 已接收到通知 * 400 - 错误的请求 * 401 - 未授权,token 可能无效 * 403 - 已禁止,manifest 中的 identity 可能不对 * 404 - 未找到 * 405 - 方法不允许 * 406 - 无法接受 * 410 - 不存在,信道不存在或过期 * 413 - 请求实体太大,限制为 5000 字节 * 500 - 内部服务器错误 * 503 - 服务不可用 */ Response.Write(webResponse.StatusCode.ToString()); //如果成功应该是返回 200 ok } } catch (Exception ex) { Response.Write(ex.ToString()); } } }}

OK

转载地址:http://jkkpx.baihongyu.com/

你可能感兴趣的文章
Windows Phone 7 中的切换“.NET研究”应用
查看>>
浅谈大型网站动态应用系统架构,互联网营销
查看>>
一起谈.NET技术,混乱的MVC,.NET非要MVC不可么?
查看>>
POJ 1094 Sorting It All Out(拓扑排序)
查看>>
(转)mysql数据库表名批量修改大小写
查看>>
罗盘开放平台设计
查看>>
JAVA注解引发的思考
查看>>
1083 是否存在相等的差 (20 分)
查看>>
[java,2017-12-01] 播放音频文件
查看>>
6大设计原则
查看>>
JavaScript与DOM的关系
查看>>
前后背景色及屏幕大小获取
查看>>
谈谈-TabPagerIndicator
查看>>
DrawerLayout和ActionBarDrawerToggle
查看>>
Unity3D--学习太空射击游戏制作(四)
查看>>
"无法从静态上下文中引用非静态变量,非静态方法"
查看>>
Mybatis中的模糊查询
查看>>
sscanf()分割字符数组
查看>>
Hibernate中使用Criteria查询及注解——( EmpCondition)
查看>>
SQL Server 关系表的创建、索引创建和数据插入
查看>>