zoukankan      html  css  js  c++  java
  • 推送通知服务【WP7学习札记之十三】

        为什么使用推送通知服务

        Windows Phone执行模型决定只有一个第三方的应用程序可以在前台运行,应用程序不能再后台运行,不断的往Cloud拉数据。微软提供推送通知服务(Push Notification)给第三方应用程序取得更新通知的消息。由于服务器能够主动的发起通信,因此可以有效的降低手机电池的消耗。

        Windows Phone 的推送通知的完整权威描述见MSDN文档描述见:http://msdn.microsoft.com/zh-cn/library/ff402537(v=vs.92).aspx

    本节内容

    推送消息的过程MS的描述是:
     

        上图显示了手机上运行的客户端应用程序如何从推送客户端服务 (1) 请求推送通知 URI。然后,推送客户端服务与 Microsoft 推送通知服务 (MPNS) 协商并向客户端应用程序(2 和 3)返回一个通知 URI。之后,客户端应用程序将此 URI 发送给云服务 (4)。当 Web 服务有要发送到客户端应用程序的信息时,该服务使用此 URI 向 Microsoft 推送通知服务 (5) 发送推送通知,Microsoft 推送通知服务又将此推送通知发送给在 Windows Phone 设备 (6) 上运行的应用程序。

          根据推送通知的格式以及连接到通知的负载,信息作为原始数据发送到应用程序、应用程序的磁贴在视觉上得到更新或显示 Toast 通知。发送推送通知之后,Microsoft 推送通知服务向您的 Web 服务发送一个响应代码,指示此通知已接收并且下次有机会会发送到设备。但是,Microsoft 推送通知服务不提供将推送通知从 Web 服务发送到设备的端到端通信。

    Jake Lin的描述是:

    使用规范:

       windows phone 7目前只允许15个第三方应用程序使用推送通知服务;

       询问用户是否使用推送通知服务;

       为用户提供取消订阅的选项。

    s消息类型:

       Raw Notification:

          可以发送任何格式的数据;

          应用程序可以根据需要加工数据;

          应用程序相关的通知消息;

          ★只有在应用程序运行时才发送。

       Toast Notification:

          发送的数据为指定的xml格式;

          ★如果应用程序正在运行,内容发送到应用程序中;

          ★如果应用程序不在运行,弹出toast消息框显示消息:

             App图标加上两个文本描述;

             打断用户当前操作,但是是临时的;

             用户可以点击进行跟踪。

        Tile Notification:

          发送的数据为指定的xml格式;

          ★不会往应用程序进行发送;

          ★如果用户把应用程序Pin to Start,那么更新数据会发送到start screen 的tile里面:

             包含三个属性,背景、标题和计数器

             每个属性都有固定的格式和位置;

             可以使用其中的属性,不一定三个属性一起用。

    示例程序示例(Raw):手机客户端代码:

    View Code
    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;

    namespace 推送通知服务
    {
    public partial class MainPage : PhoneApplicationPage
    {
    // Constructor
    public MainPage()
    {
    InitializeComponent();

    //Holds the push channel that is created or found.
    HttpNotificationChannel pushchannel;
    //The name of our push channel.
    string channelName = "RawSampleChannel";
    //Try to find the push channel
    pushchannel = HttpNotificationChannel.Find(channelName);
    // If the channel was not found, then create a new connection to the push service.
    if (pushchannel == null)
    {
    pushchannel = new HttpNotificationChannel(channelName);
    // Register for all the events before attempting to open the channel.
    pushchannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(pushchannel_ChannelUriUpdated);
    pushchannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(pushchannel_ErrorOccurred);
    pushchannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(pushchannel_HttpNotificationReceived);
    pushchannel.Open();
    }
    else
    {
    // The channel was already open, so just register for all the events.
    pushchannel.ChannelUriUpdated+=new EventHandler<NotificationChannelUriEventArgs>(pushchannel_ChannelUriUpdated);
    pushchannel.ErrorOccurred+=new EventHandler<NotificationChannelErrorEventArgs>(pushchannel_ErrorOccurred);
    pushchannel.HttpNotificationReceived+=new EventHandler<HttpNotificationEventArgs>(pushchannel_HttpNotificationReceived);
    // Display the URI for testing purposes. Normally, the URI would be passed back to your web service at this point.
    System.Diagnostics.Debug.WriteLine(pushchannel.ChannelUri.ToString());
    MessageBox.Show(String.Format("Channel Uri is {0}",
    pushchannel.ChannelUri.ToString()));
    }
    }

    void pushchannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e)
    {
    string message;

    using (System.IO.StreamReader reader = new System.IO.StreamReader(e.Notification.Body))
    {
    message = reader.ReadToEnd();
    }

    Dispatcher.BeginInvoke(() =>
    MessageBox.Show(String.Format("Received Notification {0}:\n{1}",
    DateTime.Now.ToShortTimeString(), message))
    );
    }

    void pushchannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
    {
    // Error handling logic for your particular application would be here.
    Dispatcher.BeginInvoke(() =>
    MessageBox.Show(String.Format("A push notification {0} error occurred. {1} ({2}) {3}",
    e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData))
    );
    }

    void pushchannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
    {
    Dispatcher.BeginInvoke(() =>
    {
    // Display the new URI for testing purposes. Normally, the URI would be passed back to your web service at this point.
    System.Diagnostics.Debug.WriteLine(e.ChannelUri.ToString());
    MessageBox.Show(String.Format("Channel Uri is {0}",
    e.ChannelUri.ToString()));
    });
    }
    }
    }

    云端:

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Net;
    using System.Text;
    using System.IO;

    namespace SendRaw
    {
    public partial class SendRaw : System.Web.UI.Page
    {
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void ButtonSendRaw_Click(object sender, EventArgs e)
    {
    try
    {
    // Get the URI that the Microsoft Push Notification Service returns to the push client when creating a notification channel.
    // Normally, a web service would listen for URIs coming from the web client and maintain a list of URIs to send
    // notifications out to.
    string subscriptionUri = TextBoxUri.Text.ToString();
    HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);
    // Create an HTTPWebRequest that posts the raw notification to the Microsoft Push Notification Service.
    // HTTP POST is the only method allowed to send the notification.
    sendNotificationRequest.Method = "POST";
    // Create the raw message.
    string rawMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
    "<root>" +
    "<Value1>" + TextBoxValue1.Text.ToString() + "<Value1>" +
    "<Value2>" + TextBoxValue2.Text.ToString() + "<Value2>" +
    "</root>";
    // Set the notification payload to send.
    byte[] notificationMessage = Encoding.Default.GetBytes(rawMessage);

    // Set the web request content length.
    sendNotificationRequest.ContentLength = notificationMessage.Length;
    sendNotificationRequest.ContentType = "text/xml";
    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.
    using (Stream requestStream = sendNotificationRequest.GetRequestStream())
    {
    requestStream.Write(notificationMessage, 0, notificationMessage.Length);
    }

    // Send the notification and get 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"];

    // Display the response from the Microsoft Push Notification Service.
    // Normally, error handling code would be here. In the real world, because data connections are not always available,
    // notifications may need to be throttled back if the device cannot be reached.
    TextBoxResponse.Text = notificationStatus + " | " + deviceConnectionStatus + " | " + notificationChannelStatus;
    }
    catch (Exception ex)
    {
    TextBoxResponse.Text = "Exception caught sending update: " + ex.ToString();
    }
    }

    }
    }

    运行效果截图:

    Channel Uri:

    手机端:

    云端:

  • 相关阅读:
    Springboot整合dubbo搭建基本的消费、提供和负载均衡
    SpringBoot与Dubbo整合的三种方式
    Dubbo整合SpringBoot
    Java 如何有效地避免OOM:善于利用软引用和弱引用
    finalize的作用
    垃圾回收
    不同JDK版本之间的intern()方法的区别-JDK6 VS JDK6+
    Java8内存模型—永久代(PermGen)和元空间(Metaspace)
    to meet you
    Atomic long 和long的区别
  • 原文地址:https://www.cnblogs.com/DebugLZQ/p/2396600.html
Copyright © 2011-2022 走看看