Отправить push-уведомление с устройства Windows Phone на веб-сервис

У меня вопрос по службе push-уведомлений устройства Windows Phone 7: теперь я могу отправить push-уведомление, используя веб-приложение на телефон, изменив данные плитки. Но проблема в том, что когда я запускаю приложение, мне нужно отобразить URI в выводе отладчика, а затем скопировать-вставить его внутри веб-приложения, которое, в свою очередь, свяжется с MPNS, что хорошо для обновления, один раз для один телефон. Но я хочу создать веб-сервис, который может автоматически совершать несколько вызовов, получать URI приложения (который, я думаю, изменяется после закрытия и открытия приложения) и отправлять ему push-уведомление. Но я не нашел тему 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 ) );
            } );
    }

person GeekPeek    schedule 31.01.2012    source источник
comment
Можете ли вы объяснить первую часть qn - как мне использовать телефон для отправки такого сообщения в веб-службу, ответа на него и повторного подключения к телефону, обрабатывая такой запрос.   -  person whihathac    schedule 08.02.2012


Ответы (2)


Хорошо, я понимаю ваш вопрос. Что я сделал, так это то, что как только я получаю URI от MPNS, я вызываю веб-метод для службы с этим в качестве параметра - Subscribe (int subscriberId, Uri channelUri);

Поэтому вам нужно убедиться, что вы создаете в своем приложении идентификатор subscriberId, чтобы идентифицировать пользователя и хранить его в изолированном хранилище. Это может быть GUID.

Теперь на hte-сервере лежит ответственность за сохранение отображения подписчика на Uri в постоянном хранилище.

Также вам необходимо предоставить метод UnSubscribe, чтобы пользователь мог отказаться от push-уведомления. Это одно из сертификационных требований для Push-уведомлений.

Теперь о вашем втором вопросе. Да, вам нужно будет защитить свои услуги — вы не хотите обрабатывать неизвестные запросы.

То, чем я занимаюсь лично, делю на 2 услуги — издательский сервис и сервис подписки. Служба публикации будет рассылать уведомления, а подписка будет иметь методы подписки/отписки.

person whihathac    schedule 08.02.2012
comment
Спасибо за ответ = D Я уже нашел ответ и сделал что-то подобное idd. Я еще не реализовал два отдельных веб-сервиса, что кажется очень правдоподобным, поскольку я могу управлять устройствами, получающими уведомление. - person GeekPeek; 09.02.2012

Я предполагаю, что вы пытаетесь спросить, можете ли вы отправлять push-уведомления из самого 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;
}
person Prakash Mishra    schedule 18.08.2014