将推送通知从 Windows Phone 设备发送到 Web 服务

发布于 2024-12-31 21:45:55 字数 4341 浏览 1 评论 0原文

我对 Windows Phone 7 设备的推送通知服务有疑问: 我现在可以使用 Web 应用程序向手机发送推送通知,更改磁贴的数据。但问题是:当我启动应用程序时,我需要在调试器输出中显示 URI,然后将其复制粘贴到 Web 应用程序中,这反过来会联系 MPNS,这对于更新来说很好,一旦一部电话。但我想创建一个可以自动进行多个调用的 Web 服务,检索应用程序的 URI(我认为该 URI 在关闭和打开应用程序后会发生变化)并向其发送推送通知。但我还没有找到涉及此问题的 MSDN 主题。他们只是使用推荐,说:“稍后用所需的 URI 替换。”所以我的问题是:如何使用手机向网络服务发送这样的消息,响应它,然后再次连接到手机,处理这样的请求? 另外:我是否需要经过身份验证的网络服务,或者是否有调试版本?

这是我到目前为止所拥有的:

  /// <summary>
    /// Setup a connection with a webservice, in order to update a shell, either a toast- or a tile shell.
    /// </summary>
    /// <param name="shellType">The type of shell you wish to update</param>
    public void SetupShellChannel ( ShellBindType shellType )
    {
        //holds the push notification that is created. Since we can only have one notification channel open at any one time, 
        //we will need to check for existance. That is why, the channelName shouldn't be changed
        HttpNotificationChannel _httpChannel = HttpNotificationChannel.Find( _channelName );

        //if the _httpChannel was not found ( read: does not exist )
        if ( _httpChannel == null )
        {
            _httpChannel = new HttpNotificationChannel( _channelName  );
            _httpChannel.Open( );

            //because there is more than one shelltype we can open, we will use a switch to call the method we seek
            BindToShell( _httpChannel, shellType );
        }
            //Only one push notification service is allowed per application, so we cannot send a tile notification, as well as 
            //a toast message notification. When we attempt this, we get a InvalidOperationException
        else
        { 
            //in this case, the _httpChannel did already exist, but the problem is, we cannot just add the eventHandlers, 
            //because there is the danger that it didn't exist, and we would get a null pointer exception.
            //_httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>( httpChannel_ChannelUriUpdated );
            //_httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>( httpChannel_ErrorOccurred );

            //For testing purposes, we now display the URI to the user, and as output. Normally, we would pass this URI back to the webserver
            System.Diagnostics.Debug.WriteLine( _httpChannel.ChannelUri.ToString( ) );
        }

        //if ( _httpChannel.ChannelUri )

        //When the URI is updated, we want this to be sent to the server as well, so we know that the adress has changed, 
        //and don't just send data somewhere into the void. Also, when encountering an error, we want to show the user when 
        //an error has occured.
        _httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>( HttpChannel_ChannelUriUpdated );
        _httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>( HttpChannel_ErrorOccurred );
    }

    //here, also we would return the URI to the server, but for debugging purposes, we display them to the user.
    void HttpChannel_ChannelUriUpdated( object sender, NotificationChannelUriEventArgs e )
    {
        Deployment.Current.Dispatcher.BeginInvoke( ( ) => 
        {
            System.Diagnostics.Debug.WriteLine( e.ChannelUri.ToString( ) );
            MessageBox.Show( String.Format( "the URI is {0}", e.ChannelUri.ToString( ) ) );
        } );
    }

    private void BindToShell( HttpNotificationChannel channel, ShellBindType shellType )
    {
        switch ( shellType )
        {
            case ShellBindType.BindToShellTile:
                channel.BindToShellTile( );
                break;
            case ShellBindType.BindToShellToast:
                channel.BindToShellToast( );
                break;
        }        
    }

    void HttpChannel_ErrorOccurred( object sender, NotificationChannelErrorEventArgs e )
    {
        //getting an error would be caugth here, and then displayed to the user.
        Deployment.Current.Dispatcher.BeginInvoke( ( ) =>
            {
                MessageBox.Show( String.Format( "A push notification {0} error occured. {1}{(2)}{3}", 
                    e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData ) );
            } );
    }

I have a question about the push notification service of the Windows Phone 7 device:
I can now send a push notification, using a web application to a phone, changing the data of the tile. But the problem is: when I start the app, I need to display the URI in the debugger output, and then copy-paste it inside the web application, which in turn will contact the MPNS, which is fine for an update, once to a single phone. But I want to create a webservice that can make multiple calls automatically, retrieve the URI of the application ( which changes after closing-and-opening the app, I think ) and send a push notification to it. But I haven't found an MSDN - topic that deals with this. They just use commends, saying : "to be replaced later with the URI needed." So my question is: how do I use the phone to send such a message to the webservice, respond to it, and connect to the phone again, handling such request?
and also: do I need an authenticated webservice, or is there a debug version?

This is what I have thus far :

  /// <summary>
    /// Setup a connection with a webservice, in order to update a shell, either a toast- or a tile shell.
    /// </summary>
    /// <param name="shellType">The type of shell you wish to update</param>
    public void SetupShellChannel ( ShellBindType shellType )
    {
        //holds the push notification that is created. Since we can only have one notification channel open at any one time, 
        //we will need to check for existance. That is why, the channelName shouldn't be changed
        HttpNotificationChannel _httpChannel = HttpNotificationChannel.Find( _channelName );

        //if the _httpChannel was not found ( read: does not exist )
        if ( _httpChannel == null )
        {
            _httpChannel = new HttpNotificationChannel( _channelName  );
            _httpChannel.Open( );

            //because there is more than one shelltype we can open, we will use a switch to call the method we seek
            BindToShell( _httpChannel, shellType );
        }
            //Only one push notification service is allowed per application, so we cannot send a tile notification, as well as 
            //a toast message notification. When we attempt this, we get a InvalidOperationException
        else
        { 
            //in this case, the _httpChannel did already exist, but the problem is, we cannot just add the eventHandlers, 
            //because there is the danger that it didn't exist, and we would get a null pointer exception.
            //_httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>( httpChannel_ChannelUriUpdated );
            //_httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>( httpChannel_ErrorOccurred );

            //For testing purposes, we now display the URI to the user, and as output. Normally, we would pass this URI back to the webserver
            System.Diagnostics.Debug.WriteLine( _httpChannel.ChannelUri.ToString( ) );
        }

        //if ( _httpChannel.ChannelUri )

        //When the URI is updated, we want this to be sent to the server as well, so we know that the adress has changed, 
        //and don't just send data somewhere into the void. Also, when encountering an error, we want to show the user when 
        //an error has occured.
        _httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>( HttpChannel_ChannelUriUpdated );
        _httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>( HttpChannel_ErrorOccurred );
    }

    //here, also we would return the URI to the server, but for debugging purposes, we display them to the user.
    void HttpChannel_ChannelUriUpdated( object sender, NotificationChannelUriEventArgs e )
    {
        Deployment.Current.Dispatcher.BeginInvoke( ( ) => 
        {
            System.Diagnostics.Debug.WriteLine( e.ChannelUri.ToString( ) );
            MessageBox.Show( String.Format( "the URI is {0}", e.ChannelUri.ToString( ) ) );
        } );
    }

    private void BindToShell( HttpNotificationChannel channel, ShellBindType shellType )
    {
        switch ( shellType )
        {
            case ShellBindType.BindToShellTile:
                channel.BindToShellTile( );
                break;
            case ShellBindType.BindToShellToast:
                channel.BindToShellToast( );
                break;
        }        
    }

    void HttpChannel_ErrorOccurred( object sender, NotificationChannelErrorEventArgs e )
    {
        //getting an error would be caugth here, and then displayed to the user.
        Deployment.Current.Dispatcher.BeginInvoke( ( ) =>
            {
                MessageBox.Show( String.Format( "A push notification {0} error occured. {1}{(2)}{3}", 
                    e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData ) );
            } );
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

莫多说 2025-01-07 21:45:55

好的,我明白你的问题。我所做的是,一旦从 MPNS 获取 URI,我就以此作为参数调用服务上的 Web 方法 -
订阅(intsubscriberId,UrichannelUri);

因此,您需要确保在应用程序中生成一个subscriberId来识别用户并将其存储在独立存储中。这可以是 GUID。

现在,服务器有责任将订阅者到 Uri 的映射保存在持久存储中。

此外,您还需要提供 UnSubscribe 方法,供用户选择退出推送通知。这是推送通知的认证要求之一。

现在关于你的第二个问题 - 是的,你需要保护你的服务 - 你不想处理未知的请求。

我个人所做的,分为2个服务——发布服务和订阅服务。发布服务将发出通知,而订阅将具有订阅/取消订阅方法。

Ok I understand your question. What I have done is once I get teh URI from MPNS, I call a web method on a service with this as a parameter -
Subscribe(int subscriberId, Uri channelUri);

So you need to make sure you generate a subscriberId in your app to identify a user and store it in Isolated Storage. This can be a GUID.

The onus is now upon hte server to save the Subscriber to Uri mapping in persistant storage.

Also you need to provide UnSubscribe method for user to opt out of the push notification. This is one of the certification requirement for Push notifications.

Now about your second question - Yes, you would need to secure your services - you dont want to be handling with unknown requests.

What i do personally, divide it into 2 services - Publishing service and subscription service. The Publishing service will send out hte notifications while subscription will have the subscribe/unsubscribe methods.

赤濁 2025-01-07 21:45:55

我猜您是想询问是否可以从 Windows Phone 本身发送推送通知,而不是使用任何其他服务器端 ASP/PHP,如 MSDN 中的示例应用程序中所述。是的。您可以从手机/设备本身发送通知。您只需更改 MSDN 中给出的示例应用程序的发送功能即可。如果您有任何疑问,请回复。

static async Task<string> SendPushNotification(string textToSend)
{
    //You can maintain a DB to query different channel URIs of devices
    string subscriptionUri = "<Uri To Which You Want Send Notification>";
    HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);
    sendNotificationRequest.Method = "POST";

    string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
        "<wp:Notification xmlns:wp=\"WPNotification\">" +
           "<wp:Toast>" +
                "<wp:Text1>" + textToSend + "</wp:Text1>" +
                "<wp:Param>/NotificationDetails.xaml?Message=" + textToSend + "</wp:Param>" +
           "</wp:Toast> " +
        "</wp:Notification>";
    byte[] notificationMessage = Encoding.UTF8.GetBytes(toastMessage);

    sendNotificationRequest.ContentLength = notificationMessage.Length;
    sendNotificationRequest.ContentType = "text/xml";
    sendNotificationRequest.Headers["X-WindowsPhone-Target"] = "toast";
    sendNotificationRequest.Headers["X-NotificationClass"] = "2";

    using (var requestStream = await Task.Factory.FromAsync<Stream>(sendNotificationRequest.BeginGetRequestStream, sendNotificationRequest.EndGetRequestStream, null))
    {
        requestStream.Write(notificationMessage, 0, notificationMessage.Length);
    }

    string notificationStatus;
    using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(sendNotificationRequest.BeginGetResponse, sendNotificationRequest.EndGetResponse, null)))
    {
        //StreamReader reader = new StreamReader(response.GetResponseStream());
        //result = reader.ReadToEnd();
        notificationStatus = response.Headers["X-NotificationStatus"];
        MessageBox.Show(notificationStatus);
    }
    return notificationStatus;
}

I guess you are trying to ask that you can send push notification from Windows Phone itself or not instead using any other server side ASP/PHP like explained in Sample Applications in MSDN. Yes. You can send notifications from phone/device itself. You have to just change Send function of Sample app as given in MSDN. Reply if you have any queries.

static async Task<string> SendPushNotification(string textToSend)
{
    //You can maintain a DB to query different channel URIs of devices
    string subscriptionUri = "<Uri To Which You Want Send Notification>";
    HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);
    sendNotificationRequest.Method = "POST";

    string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
        "<wp:Notification xmlns:wp=\"WPNotification\">" +
           "<wp:Toast>" +
                "<wp:Text1>" + textToSend + "</wp:Text1>" +
                "<wp:Param>/NotificationDetails.xaml?Message=" + textToSend + "</wp:Param>" +
           "</wp:Toast> " +
        "</wp:Notification>";
    byte[] notificationMessage = Encoding.UTF8.GetBytes(toastMessage);

    sendNotificationRequest.ContentLength = notificationMessage.Length;
    sendNotificationRequest.ContentType = "text/xml";
    sendNotificationRequest.Headers["X-WindowsPhone-Target"] = "toast";
    sendNotificationRequest.Headers["X-NotificationClass"] = "2";

    using (var requestStream = await Task.Factory.FromAsync<Stream>(sendNotificationRequest.BeginGetRequestStream, sendNotificationRequest.EndGetRequestStream, null))
    {
        requestStream.Write(notificationMessage, 0, notificationMessage.Length);
    }

    string notificationStatus;
    using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(sendNotificationRequest.BeginGetResponse, sendNotificationRequest.EndGetResponse, null)))
    {
        //StreamReader reader = new StreamReader(response.GetResponseStream());
        //result = reader.ReadToEnd();
        notificationStatus = response.Headers["X-NotificationStatus"];
        MessageBox.Show(notificationStatus);
    }
    return notificationStatus;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文