Push notifications: realizziamo l’applicazione server

Print Content | More

Nel post precedente abbiamo realizzato il servizio che, per il nostro progetto di esempio sulle notifiche push, fa da ponte tra l’applicazione server e la nostra applicazione Windows Phone. E’ giunto il momento di realizzare l’applicazione server vera e propria, che si occuperà di inviare le notifiche push verso i device registrati

Premessa: l’esempio che andremo a realizzare è molto semplice, in uno scenario reale avrebbe senso implementare nella nostra applicazione molte più feature. Ci torneremo in un secondo momento.

Mettiamoci al lavoro: un client WPF

La tecnologia scelta per realizzare l’applicazione server è WPF, il “fratello maggiore” di Silverlight. Realizzeremo una semplicissima applicazione Windows che, alla pressione di un tasto, invierà la notifica al device e mostrerà a video la risposta ottenuta dal Microsoft Push Notification Server (che, vi ricordo, è il servizio on the cloud di Microsoft che si occupa di inviare le notifiche ai device per conto vostro).

Apriamo Visual Studio e, nella stessa soluzione che abbiamo creato nel post precedente per il servizio, aggiungiamo un nuovo progetto di tipo WPF Application (che troviamo sotto la voce Windows).

Come prima cosa cosa, dobbiamo predisporre l’applicazione per utilizzare la Push Notication Server Library di Microsoft: come anticipato nel post introduttivo a questo tutorial, si tratta di una “recipe” pubblicata dal team di Windows Phone che vi facilità la vita nella gestione delle notifiche push nella vostra applicazione server. Come sapete, le notifiche push non sono nient’altro che XML che vengono spediti tramite una chiamata HTTP in POST verso l’URL del canale: in condizioni normali, nella vostra applicazione dovreste definire il formato dei vari XML, aggiungere tutti gli header necessari, formattarli correttamente e poi, dopo l’invio, predisporvi a leggere la risposta del Push Notification Server. La libreria di Microsoft vi fa risparmiare tempo, facendo tutto questo per voi ed evitando di dover riscrivere sempre lo stesso codice in ogni progetto: tale libreria vi mette a disposizione tre oggetti diversi, uno per ogni tipo di notifica push, che accettano in input i vari parametri che identificano la notifica (ad esempio, nel caso di una notifica toast titolo e messaggio) e che espongono il metodo Send, che effettua l’invio vero e proprio, e che tramite un evento di callback, vi restituisce le informazioni sull’esito dell’operazione.

Scarichiamo perciò la recipe dal sito ufficiale e scompattiamola in una cartella: uno dei progetti contenuti all’interno della soluzione si chiama WindowsPhone.Recipes.Push.Messasges. Questa è la libreria vera e propria, che dovremo aggiungere allla nostra soluzione: possiamo aggiungere direttamente l’intero progetto (tasto destro sulla soluzione e scegliamo Add Existing Project) oppure possiamo aprirlo, compilarlo e aggiungere solo una reference alla DLL chiamata WindowsPhone.Recipes.Push.Messasges.dll.

Ora che è tutto pronto possiamo iniziare lo sviluppo e vero proprio. Partiamo dall’interfaccia grafica, molto semplice, ovvero tre pulsanti per inviare i tre tipi di notifica esistenti. Ecco il codice della MainWindow.xaml, ovvero la pagina che viene caricata all’avvio della nostra applicazione.

<Grid>
    <Button Content="Send toast" Height="23" HorizontalAlignment="Left" Margin="33,27,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" />
    <Button Content="Send tile" Height="23" HorizontalAlignment="Left" Margin="155,27,0,0"  VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
    <Button Content="Send raw" Height="23" HorizontalAlignment="Left" Margin="279,27,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2" />
</Grid>

Il secondo step è quello di aggiungere una reference al nostro servizio WCF, così da poter recuperare l’elenco dei device: clicchiamo con il tasto destro sul nostro progetto e scegliamo Add Service Reference. Dato che il servizio fa parte della stessa soluzione, non abbiamo bisogno di fare l’host su un server Web, ma ci penserà direttamente Visual Studio. Ci basta premere il pulsante Discover e automaticamente verranno trovati tutti i servizi disponibili: a questo punto possiamo aggiungere una reference a PushService.

Vediamo ora il codice di esempio dell’evento Button_Click, che viene invocato quando mandiamo una notifica toast a tutti i device.

private void Button_Click(object sender, RoutedEventArgs e)
{
    List<Device> devices = new List<Device>();

    PushServiceClient client = new PushServiceClient();
    ToastPushNotificationMessage toast = new ToastPushNotificationMessage
    {
        SendPriority = MessageSendPriority.High,
        SubTitle = "Subtitle",
        Title = "Title"
    };

    client.RetrieveAllDevicesCompleted += (obj, parameter) =>
                                              {
                                                  devices = parameter.Result;
                                                  foreach (Device device in devices)
                                                  {
                                                      toast.SendAsync(new Uri(device.ChannelUri),
                                                                      result =>
                                                                      MessageBox.Show(
                                                                          result.NotificationStatus.ToString()),
                                                                      error =>
                                                                      MessageBox.Show(error.Exception.Message));
                                                  }
                                              };
    client.RetrieveAllDevicesAsync();
}

La prima cosa che facciamo è definire la nostra notifica, creando una nuova istanza della classe ToastPushNotificationMessage. Ogni notifica espone proprietà specifiche per il suo tipo: ecco perciò che questo oggetto espone le proprietà Title e SubTitle, la notifica di tipo Tile espone invece le proprietà Count e BackgroundImageUri e così via. Una proprietà in comune a tutti è SendPriority, che identifica la priorità che ha la nostra notifica. Viene accettato uno dei tre valori dell’enumeratore di tipo MessageSendPriority, ovvero Low, Medium e High. Più è bassa la priorità, maggiore sarà il tempo necessario affinchè questa venga ricevuta dal device. Siccome in questo momento vogliamo testare subito se la nostra applicazione funziona, utilizziamo la priorità High, che consiste nell’invio in tempo reale.

E’ giunto il momento di chiamare il nostro servizio per recuperare tutti i device: creiamo una istanza del PushServiceClient e ci sottoscriviamo all’evento RetrieveAllDevicesCompleted, che viene invocato nel momento in cui il servizio ha terminato le operazioni lato server ed ha restituito il risultato dell’elaborazione. La sintassi che utilizziamo è quella degli anonymous delegates, ovvero non definiamo un nuovo evento con un nome ben preciso al di fuori del blocco di codice corrente  ma lo facciamo direttamente inline. In questo modo, possiamo accedere agli oggetti e alle variabili dichiarate all’interno del metodo Button_Click (nel nostro caso, l’oggetto toast) senza bisogno ad esempio di definirle come variabili globali.

L’oggetto parameter (che contiene gli argomenti di ritorno della callback) espone la proprietà Result, che contiene il risultato dell’elaborazione, ovvero la collection con tutti i device memorizzati nel database. Con un ciclo foreach passiamo in rassegna tutti i device disponibili e, per ognuno di essi, chiamiamo il metodo SendAsync esposto dalla notifica (di questo metodo esiste anche la versione sincrona, chiamata semplicemente Send, ma per evitare che la UI della nostra applicazioni si blocchi fino a che non è stata ricevuta una risposta ho preferito usare il metodo asincrono).

Il metodo SendAsync accetta tre parametrI:

  • l’URL del canale a cui spedira la notifica, di tipo Uri, che recuperiamo dall’oggetto di tipo Device che stiamo iterando in quel momento.
  • Un evento di callback che viene chiamato nel momento  in cui l’operazione è andata a buon fine. Nel nostro caso, mostriamo semplicemente un messaggio a video con lo stato dell’invio.
  • Un evento di callbak che viene chiamato nel momento in cui si è verificato un errore. Nel nostro caso, mostriamo un messaggio di errore con l’eccezione.

L’argomento di ritorno del metodo SendAsync (nel nostro esempio si chiama Result) espone parecchie informazioni sull’esito dell’invio (come il codice della risposta), che sarebbe utile mantenere e tracciare in una applicazione client più completa.

Come dicevo all’inizio, infatti, l’esempio che abbiamo realizzato è molto semplice. Un client vero e proprio potrebbe implementare una serie di feature ulteriori quali:

  • Salvare in un database lo storico delle risposte ricevute in seguito agli invii delle notifiche, così da mantenere per ogni device un log di quello che è stato fatto.
  • Sfruttare i codici di ritorno per implementare un rudimentale QoS: il Push Notification Service di Microsoft infatti non offre un servizio che assicuri la corretta ricezione della notifica, ma si limita a riportarvi l’esito dell’invio. Sarebbe interessante implementare, ad esempio, un meccanismo di retry automatico dell’invio dopo un certo periodo di tempo nel caso in cui la notifica sia stata rifiutata per problemi di connettività (ad esempio, il device si trovava in quel momento in una zona dove non c’era segnale). Oppure ancora un meccanismo di fallback, per cui se ad esempio inviamo una notifica raw ma il MPNS ci risponde che l’applicazione in quel momento è chiusa, optare per una toast.
  • Dare la possibilità di inviare una notifica ad un singolo device (o ad un gruppo di device): abbiamo già implementato un metodo nel servizio per ottenere questo risultato, ma al momento non è stato utilizzato nella realizzazione dell’applicazione server.

Largo alla fantasia perciò: scopo di questo post era darvi le basi necessarie per capire il meccanismo di invio delle notifiche push e la gestione dei relativi messaggi di ritorno. Ora tocca a voi darvi da fare per implementare la soluzione più adatta alle vostre esigenze!

Nel prossimo post vedremo l’unica parte del progetto che ci manca da realizzare: il client Windows Phone che riceverà le notifiche. Alla prossima!


Windows Phone , Microsoft , Push notifications

0 comments

Related Post


(will not be published)
(es: http://www.mysite.com)