Windows Phone 7 - 推送通知服務

Windows Phone 中的 Microsoft Push Notification Service 向第三方開發人員提供了一個彈性,專注,而且持續的渠道,使得開發人員可以從Web Service 向移動應用程序發送信息和更新。

過去移動應用程序需要經常主動訪問相應的WEB服務,以了解是否有任何等待處理的通知。這樣做是有效的,但會導航手機無線設備頻繁打開,從而對 電池續航時間或者用戶的流量帶來負面 影響。使用推送通知的方式取代主動調查,Web Service 能夠提醒應用程序獲取所需要的重要理更新。

當一個Web Service 有信息要發送到應用程序,它先發送一個通知到Push Notification Service ,該服務隨后將通知應用程序,應用程序的標題明顯地更新或者顯示一個Toast 通知。然后,如果需要的話,應用程序可以使用自己的的協議聯系Web service 以獲取更新。

關于推送通知服務,看了Jake Lin 的視頻他說的“好萊塢原則”己經說得很清楚了,不過我自己從現實中的淘寶購物也產生了一定的理解,下面跟大家分享一下,給出圖示:

Windows Phone 7 - 推送通知服務

如上圖,我們可以把推送通知理解成,一部手機就相當于我們一個用 戶,在淘寶注冊了帳號并填寫了送貨地址(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





   




         (httpChannel_ChannelUriUpdated);

            //發生錯誤的事件
            httpChannel.ErrorOccurred += new EventHandler





    




           (httpChannel_ErrorOccurred);
            //Raw 推送通知服務事件
            httpChannel.HttpNotificationReceived += new EventHandler





     




             (httpChannel_HttpNotificationReceived);

            //toast 推送通知服務事件
            httpChannel.ShellToastNotificationReceived += new EventHandler





      




               (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





   




         (httpChannel_ChannelUriUpdated);

            //發生錯誤的事件
            httpChannel.ErrorOccurred += new EventHandler





    




           (httpChannel_ErrorOccurred);
            //Raw 推送通知服務事件
            httpChannel.HttpNotificationReceived += new EventHandler





     




             (httpChannel_HttpNotificationReceived);

            //toast 推送通知服務事件
            httpChannel.ShellToastNotificationReceived += new EventHandler





      




               (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 = "





   " +
                        "





   




   





    " +
                           "





    




           " +
                              "





     




             天氣更新





     " +
                              "





     




             " + msg + "





     " +
                           "





    " +
                        "





   ";
                byte[] strBytes = new UTF8Encoding().GetBytes(toastMessage);
                sendNotificationType(strBytes,notificationType.toast);
            }
            else if (type == "Tile")
            {
                string tileMessage = "





   " +
                    "





   





    " +
                       "





    




           " +
                          "





     




             /Images/" + WeatherComboBox.Text + ".png





     " +
                          "





     




             " + TemperatureTextBox.Text + "





     " +
                          "





     




             " + LocationComboBox.Text + "





     " +
                       "





     " +
                    "





   ";
                byte[] strBytes = new UTF8Encoding().GetBytes(tileMessage);
                sendNotificationType(strBytes, notificationType.tokens);
            }
        }

注:本篇URI是通過打印得到。然后賦值給Windows Form 應用程序,如下圖:

Windows Phone 7 - 推送通知服務

例子運行效果如下圖:

Windows Phone 7 - 推送通知服務

上圖為Raw notification運行效果

 

Windows Phone 7 - 推送通知服務

運行時的Toast

Windows Phone 7 - 推送通知服務

不運行時的Taost

 

Windows Phone 7 - 推送通知服務

Tokens 運行效果

 

源碼下載:

推送通知服務

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!