Windows Phone 7 學習筆記 - 推送通知服務

fmms 12年前發布 | 35K 次閱讀 Windows Phone開發 移動開發 Windows Phone 7

大家都知道windows phone值允許一個第三方的應用程序在前臺運行,所以應用程序就不能在后臺從服務器上取數據。所以微軟提供推送通知服務給第三方應用程序取得更新通知的消息,讓用戶覺得這個程序運行在后臺。

熟悉C/S架構、B/S架構的朋友都知道,C/S架構中客戶端到服務器的消息傳輸可以是雙向的,客戶端即可以主動從服務器獲取消息,也可以被動 接受來自服務器通知。而B/S架構瀏覽器只能主動從服務器獲取消息,也就是說如果瀏覽器沒有請求,服務器是不可能傳輸數據給客戶端的。由此看來 windows phone是C/S模式,同時微軟不允許手機被動接收服務器的消息,但是這樣無法實現服務器通知。WP提供了一種代理的機制來實現服務器通知,這就是推送 通知。

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

1、推送消息的過程

推送通知是一種云服務器代理,服務器不能直接向手機客戶端發送消息,必須通過云服務器代理發送。

步驟如下:

(1)Window Phone客戶端應用程序請求與微軟推送通知服務(Microsoft Push Notification Services)建立通道連接,微軟推送通知服務(Microsoft Push Notification Services)使用通道URI響應。

(2)Window Phone客戶端應用程序向監視服務(Web Service或者Cloud Application)發送包含推送通知服務通道URI以及負載的消息。

(3)當監視服務檢測到信息更改時(如航班取消、航班延期或天氣警報),它會向微軟推送通知服務(Microsoft Push Notification Services)發送消息。

(4)微軟推送通知服務(Microsoft Push Notification Services)將消息中繼到Windows Phone設備,由Window Phone客戶端應用程序處理收到的消息。

(5)需要時WP設備往Cloud服務讀取更多的數據

Windows Phone 7 學習筆記 - 推送通知服務

當一個Web service信息發送到應用程序,它發送一個通知Push Notification Service該服務隨后將通知路由到應用程序。根據推送通知的格式和裝載量,信息作為原始數據傳遞到應用程序,應用程序的標題明顯地更新或顯示一個Toast通知。然后如果需要的話應用程序可以使用自己的協議聯系web service以獲取更新。

Push Notification Service在推送通知發送后向你的web service發送一個回復碼.然而,Push Notification Service不能為你的推送提醒是否成功傳遞到應用程序提供端到端的確認。

另外一種圖解如下:

(1)客戶端從推送云服務(MPNS)獲取通知URI,提交給自己的第三方服務器。

Windows Phone 7 學習筆記 - 推送通知服務

 

(2)自己的第三方服務器的通過URI提交通知給推送云服務(MPNS),推送云服務(MPNS)推送通知到手機。

Windows Phone 7 學習筆記 - 推送通知服務

 

2、消息類型

(1)Raw Notification

  •      可以發送任何格式的數據,格式可以任意設定;
  •      應該程序可以根據需要加工數據;
  •      應用程序相關(application-specific)的通知消息;
  •      只有在應用程序運行時,才發送.如果當前沒有運行您的應用程序,Raw通知將被微軟推通知服務丟棄,不會傳遞到Windows Phone設備。

(2)Toast Notification

  •      發送的數據為指定的xml格式;
  •      如果應用程序正在運行,內容發送到應用程序中;
  •      如果應用程序不在運行,彈出Tost消息框顯示消息;

          a.App圖標加上兩個文本描述:標題與副標題,標題為粗體字顯示的字符串,副標題為非粗體字顯示的字符串;

          b.打斷用戶當前的操作,但是是臨時的,且不破壞用戶的工作流,十秒鐘后自動消失;

          c.用戶可以點擊進行跟蹤。

Windows Phone 7 學習筆記 - 推送通知服務

 

(3)Tile Notification

  •      發送的數據為指定的XML格式;
  •      不會往應用程序進行發送;
  •      如果用戶把應用程序pin to start,那么更新數據發送到start screen的tile里面。

           a.包含三個屬性,背景(background)、標題(title)和計算器(count);
           b.每個屬性都有固定的格式與位置;
           c.可以使用其中的屬性,不一定三個屬性一起使用。

Windows Phone 7 學習筆記 - 推送通知服務

 

例子,有點長哈:

用一個WebForm作為服務器端:

Windows Phone 7 學習筆記 - 推送通知服務

Form1.cs

private void SendButton_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);
                SendRawNotification(strBytes);
            }
            else if (type == "Toast")
            {
                string toastMessage = "" +
                        "" +
                           "" +
                              "天氣更新" +
                              "" + msg + "" +
                           "" +
                        "";
                byte[] strBytes = new UTF8Encoding().GetBytes(toastMessage);
                SendToastNotification(strBytes);
            }
            else if (type == "Tile")
            {
                string tileMessage = "" +
                    "" +
                       "" +
                          "/Images/" + WeatherComboBox.Text + ".png" +
                          "" + TemperatureTextBox.Text + "" +
                          "" + LocationComboBox.Text + "" +
                       " " +
                    "";
                byte[] strBytes = new UTF8Encoding().GetBytes(tileMessage);
                SendTileNotification(strBytes);
            }
        }

        private void SendTileNotification(byte[] Payload)
        {
            // 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();

            // 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.

            // 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 SendToastNotification(byte[] Payload)
        {
            // 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();

            // 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 SendRawNotification(byte[] Payload)
        {
            // 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();

            // 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.

            // 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);
        }

windows phone端

Windows Phone 7 學習筆記 - 推送通知服務

MainPages.xaml.cs

private HttpNotificationChannel httpChannel;
        private const string channelName = "Channel1";

private void button1_Click(object sender, RoutedEventArgs e)
        {
            httpChannel = HttpNotificationChannel.Find(channelName);

            //Delete the Channel if exists
            if (httpChannel != null)
            {
                httpChannel.Close();

                httpChannel.Dispose();
            }

            //Create the channel
            httpChannel = new HttpNotificationChannel(channelName, "NotificationService");

            //Register to UriUpdated event - occurs when channel successfully opens
            httpChannel.ChannelUriUpdated += new EventHandler(httpChannel_ChannelUriUpdated);

            //general error handling for push channel
            httpChannel.ErrorOccurred += new EventHandler(httpChannel_ErrorOccurred);

            //Subscribed to Raw Notification
            httpChannel.HttpNotificationReceived += new EventHandler(httpChannel_HttpNotificationReceived);

            //Open the channel
            httpChannel.Open();

            //subscrive to toast notification when running app    
            httpChannel.ShellToastNotificationReceived += new EventHandler(httpChannel_ShellToastNotificationReceived);

            //subscrive to toast notification
            httpChannel.BindToShellToast();

            //subscrive to tile notification
            httpChannel.BindToShellTile();
        }

        void httpChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
        {
            string msg = "";
            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)
        {
            using (var reader = new StreamReader(e.Notification.Body))
            {
                string msg = reader.ReadToEnd();
                Dispatcher.BeginInvoke(() =>
                {
                    MsgTextBlock.Text = msg;
                });
            }
        }

        void httpChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
        {
            Dispatcher.BeginInvoke(() =>
            {
                MsgTextBlock.Text = e.Message;
            });
        }

        void httpChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
        {
            Debug.WriteLine("ChannelUri: {0}", e.ChannelUri);
        }

3、不使用推送通知定時更新Tile

(1)定時自動更新Tile
      (2)支持Update一次或者多次
      (3)只支持網絡圖片,圖片小雨80k,而且最多使用15秒鐘下載
(4)最短間隔為1小時

 

4、使用規范

(1)當前版本的Window Phone只支持最多15個第三方應用程序使用推送通知服務
(2)詢問用戶是否使用推送通知服務
(3)為用戶提供取消訂閱的選項


參考鏈接:How to: Send a Push Notification for Windows Phone

http://msdn.microsoft.com/en-us/library/ff402545(VS.92).aspx

How to: Receive Push Notifications in an Application for Windows Phone

http://msdn.microsoft.com/zh-cn/library/ff402556%28v=VS.92%29.aspx

推送通知服務

http://www.cnblogs.com/dnso/articles/1961814.html

Windows Phone 7編程實踐—推送通知_剖析推送通知實現架構

http://www.cnblogs.com/xuesong/archive/2011/04/08/2008987.html

WP7應用開發筆記(15) 推送通知

http://www.cnblogs.com/kiminozo/archive/2012/01/28/2330516.html

 

原文鏈接:http://www.cnblogs.com/zhangkai2237/archive/2012/02/19/2358331.html

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