Notyfikacje push

Udostępnij na: Facebook

Autor: Marcin Kruszyński

Opublikowano: 2011-02-14

Pobierz i uruchom

Często zdarza się, że potrzebujemy wysyłać powiadomienia od serwera do klienta. W Windows Phone 7 mamy możliwość skorzystania z notyfikacji push, które pod różnymi względami są lepszym rozwiązaniem niż okresowe odpytywanie serwisu (polling).

Po przeczytaniu tego artykułu będziesz:

  • wiedział, dlaczego notyfikacje push są lepsze od pollingu,
  • znał dokładnie działanie mechanizmu notyfikacji push,
  • znał rodzaje notyfikacji i ich właściwości,
  • wiedział, jak zaimplementować serwis wysyłający notyfikacje i klienta, który je odbiera.  

Wprowadzenie

Microsoft Push Notification Service (MPNS) jest usługą w chmurze, za pomocą której możemy przesyłać powiadomienia do użytkowników aplikacji na Windows Phone 7. W tym przypadku komunikacja inicjalizowana jest przez serwer, co pozwala nam zmniejszyć zużycie baterii. W porównaniu z pollingiem notyfikacje push mają jeszcze jedną zaletę – mogą być odbierane nawet wtedy, gdy aplikacja, dla której były przeznaczone, nie jest uruchomiona. Warto zwrócić na to uwagę, ponieważ nie mamy możliwości pisania aplikacji wykonujących się w tle.

Sposób działania

Działanie mechanizmu notyfikacji push zostało przedstawione na rys. 1.

**Rys.1. Sposób działania notyfikacji push.

Microsoft Push Notification Service pośredniczy w wysyłaniu powiadomień z serwisu firmy trzeciej do aplikacji mobilnej. Aby było to możliwe, serwis firmy trzeciej powinien umieć identyfikować telefon.

W tym celu aplikacja WP7 rejestruje się najpierw w MPNS, a potem w serwisie firmy trzeciej. Pierwszą czynnością jest otwarcie kanału notyfikacji do MPNS (krok 1). Obowiązują jednak pewne ograniczenia – na daną aplikację może przypadać maksymalnie 1 kanał, a na całe urządzenie - 15. MPNS zwraca Uri, jednoznacznie identyfikujące instancję aplikacji na danym telefonie. Aplikacja może także określić, jakie rodzaje notyfikacji chce otrzymywać. Następnie musi zarejestrować się także w serwisie firmy trzeciej, by przekazać mu poprzednio uzyskane Uri kanału notyfikacji (krok 2).

Jeśli serwis firmy trzeciej będzie chciał przekazać informację do mobilnej aplikacji, to wysyła wiadomość na przekazane mu Uri (krok 3). Jest to adres endpointa hostowanego przez MPNS, który przekazuje notyfikację do odpowiedniego urządzenia po jego zlokalizowaniu (krok 4).

Rodzaje notyfikacji

Wyróżniamy trzy rodzaje notyfikacji push:

  • raw,
  • toast,
  • tile.

Na rys. 2 pokazano różnice między notyfikacjami toast i tile.

**Rys.2. Notyfikacje toasti tile.

Notyfikacje raw mają zawartość o maksymalnym rozmiarze 1kB, a ich format jest specyficzny dla danej aplikacji. Tego rodzaju notyfikacje mogą być odbierane tylko przez działającą aplikację. Jeśli aplikacja się nie wykonuje, MPNS porzuca notyfikację i nie dostarcza jej do urządzenia.

Notyfikacje toast mają ściśle określony format swojej zawartości za pomocą schematu XML.

Zawartość dostarczana jest do działającej aplikacji. Jeśli aplikacja się nie wykonuje, system na podstawie zawartości wiadomości wyświetla w górnej części ekranu specjalny popup. Komunikat jest widoczny przez 10 sekund. Gestem flick możemy spowodować jego zniknięcie. Jeśli użytkownik naciśnie komunikat, zostanie uruchomiona związana z nim aplikacja.

W notyfikacji toast możemy aktualizować jej dwa tekstowe elementy (rys.2). Zawsze wyświetlana jest pomniejszona ikona aplikacji i nie mamy możliwości przekazania do komunikatu innej ikony.

Zalecenia dotyczące notyfikacji toast:

  • powinny być istotne dla danego użytkownika i krytyczne w czasie,
  • w pierwszej kolejności powinny być ukierunkowane na komunikację peer-to-peer,
  • nie należy ich nadużywać, bo w nadmiarze mogą drażnić użytkownika.

Warunki certyfikacji określają, że notyfikacje toast zawsze powinny być włączane za zgodą użytkownika, a w UI aplikacji lub jej konfiguracji powinna być możliwość ich wyłączenia.

Każda aplikacja posiada skrót w postaci kafelka (tile), będącego jej wizualną reprezentacją (lub jej zawartości). Na ekranie startowym jest wyświetlany wtedy, jeśli użytkownik go przypiął.

Notyfikacje tile mają określony format swojej zawartości również za pomocą schematu XML. 

Nigdy nie są dostarczane do aplikacji. Jeśli użytkownik przypiął kafelek na ekranie startowym, system dokonuje jego aktualizacji na podstawie zawartości wiadomości. Notyfikacje tile mogą kontrolować obrazek tła, tytuł oraz licznik (rys. 2).

Obrazek tła może odnosić się do lokalnego zasobu bedącego częścią pakietu .xap lub do zdalnego, w sieci. Wyświetlanie lokalnych obrazków jest zalecane ze względu na lepszą wydajność i mniejsze zużycie baterii. Korzystanie z referencji na obrazek w sieci umożliwia jego dynamiczną aktualizację. Maksymalny rozmiar umieszczonego w sieci obrazka wynosi 80kB, a czas jego pobierania – 15 sekund.

Jeśli w notyfikacji tytuł nie został określony, to na kafelku zostanie wyświetlony dotychczasowy. 

Licznik wyświetla liczby całkowite od 1 do 99. Jeśli notyfikacja nie zawiera liczby lub zawiera liczbę całkowitą spoza podanego zakresu, na kafelku będzie nadal wyświetlany dotychczasowy numer. Jeśli do tej pory licznik nie był widoczny, nic się nie zmienia. Wysłanie notyfikacji z wartością 0 powoduje zniknięcie licznika.

Obecnie nie jest możliwe dokonywanie aktualizacji naszego kafelka z użyciem animacji i dźwięku, a w przypadku tytułu i licznika nie możemy też zmieniać ich położenia ani wyglądu.  

Istnieje również alternatywny sposób na odświeżanie obrazka w kafelku bez potrzeby korzystania z notyfikacji push, tzn. możemy ustawić harmonogram, w którym określimy adres webowy, przedział czasu i częstotliwość aktualizacji obrazka. Więcej informacji na ten temat znajdziesz w dokumentacji na stronie How to: Update Your Tile Without Push Notifications for Windows Phone.

W zależności od rodzaju aplikacji i danego scenariusza stosujemy jeden lub więcej rodzajów notyfikacji. Na przykład do wyświetlania temperatury użyjemy notyfikacji tile, a do przekazywania aktualności – notyfikacji toast. Rolę uzupełniającą względem wymienionych rodzajów pełni notyfikacja raw, pozwalająca na bezpośrednie przekazywanie informacji do wykonującej się aplikacji.

Wyczerpana bateria powoduje ograniczenia w odbiorze notyfikacji przez telefon. Przy niskim poziomie naładowania odbierane są tylko notyfikacje raw, przy krytycznie niskim – żadne.  

Implementacja webserwisu

Przedstawimy implementację wybranych elementów webserwisu komunikującego się z MPNS.

Wysyłanie notyfikacji do MPNS może wyglądać następująco:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(channelUri);
request.Method = WebRequestMethods.Http.Post;
request.ContentLength = payload.Length;
request.ContentType = "text/xml"; 

request.Headers["X-MessageID"] = Guid.NewGuid().ToString();
//token, toast  
request.Headers["X-WindowsPhone-Target"] = "token";
//tile: 1, 11–450s, 21–900s; toast: 2, 12–450s, 22–900s; raw: 3, 13–450s, 23–900s
request.Headers["X-NotificationClass"] = "1";
    
using (Stream requestStream = request.GetRequestStream())
{
    requestStream.Write(payload, 0, payload.Length);
}
                
WebResponse response = request.GetResponse()

HTTP POST jest jedynym dozwolonym sposobem wysyłania notyfikacji.

Rodzaj zawartości w przypadku notyfikacji toast i tile powinien być określony jako text/xml.

Zawartość notyfikacji toast wygląda następująco:

<?xml version="1.0" encoding="utf-8"?>
<wp:Notification xmlns:wp="WPNotification">
  <wp:Toast>
    <wp:Text1><string></wp:Text1>
    <wp:Text2><string></wp:Text2>
  </wp:Toast>
</wp:Notification>

a w przypadku notyfikacji tile tak:

<?xml version="1.0" encoding="utf-8"?>
<wp:Notification xmlns:wp="WPNotification">
  <wp:Tile>    
    <wp:BackgroundImage><background image path></wp:BackgroundImage>
    <wp:Count><count></wp:Count>
    <wp:Title><title></wp:Title>    
  </wp:Tile>  
</wp:Notification>

Definiowanie niestandardowych nagłówków HTTP w wysyłanym powiadomieniu jest opcjonalne. Nagłówek X-MessageID pozwala jednoznacznie zidentyfikować wysyłaną wiadomość, a także powoduje umieszczenie tej samej wartości w odpowiedzi. Nagłówek X-WindowsPhone-Target określa rodzaj notyfikacji. W przypadku notyfikacji toast i tile ustawiamy jego wartość odpowiednio na toast i token. Gdy nie ma tego nagłówka, notyfikacja jest traktowana jako raw. Za pomocą nagłówka X-NotificationClass możemy zdecydować, kiedy notyfikacja z MPNS zostanie wysłana do aplikacji na telefonie. Może to nastąpić niezwłocznie albo z opóźnieniem 450 s i 900 s. Gdy nagłówek ten nie występuje, notyfikacje są przesyłane niezwłocznie. Więcej na temat niestandardowych nagłówków możesz przeczytać na stronie Push Notification Custom HTTP Headers for Windows Phone.

Po wysłaniu notyfikacji serwis otrzymuje kody odpowiedzi oraz opcjonalnie niestandardowe nagłówki HTTP. Szczegółowe informacje znajdziesz w dokumentacji na stronie Push Notification Service Response Codes for Windows Phone.

Dla zwiększenia bezpieczeństwa zaleca się stosowanie webserwisu z HTTPS. Szczegółowe informacje na temat wymaganych certyfikatów i ich obsługi w Marketplace znajdziesz w dokumentacji na stronie How to: Set up an Authenticated Web Service for Windows Phone. Zautentykowane serwisy nie mają dziennego limitu 500 notyfikacji oraz pozwalają na zarejestrowanie callbacku.  Moment wywoływania callbacku oraz jego rejestrację opisuje dokumentacja na stronie How to: Set up a Callback Registration Request for Windows Phone.   

Implementacja klienta

Do implementacji klienta odbierającego notyfikacje push wykorzystujemy głównie klasę HttpNotificationChannel. Odpowiada ona za tworzenie kanału między MPNS a klientem i za subskrypcję na różne rodzaje notyfikacji.

Zanim jednak zaczniemy tworzyć nowy kanał, sprawdźmy, czy kanał o danej nazwie już nie istnieje. Używamy do tego metody Find w klasie HttpNotificationChannel. Jeśli go znajdziemy, to zapisujemy się na jego zdarzenia, rejestrujemy się w serwisie, który będzie wysyłał wiadomości do MPNS, oraz dokonujemy subskrypcji na notyfikacje tile i toast. Więcej informacji o tych operacjach przedstawimy w trakcie dalszego omawiania implementacji klienta.

httpChannel = HttpNotificationChannel.Find(channelName);

if (httpChannel != null)
{
    SubscribeToChannelEvents();
    SubscribeToService();
    SubscribeToNotifications();                
}
else
{
    httpChannel = new HttpNotificationChannel(channelName, serviceName);
    SubscribeToChannelEvents();
    httpChannel.Open();           
}

W przypadku nieznalezienia kanału, tworzymy nowy. Konstruktor klasy HttpNotificationChannel przyjmuje dwa parametry – nazwę kanału oraz nazwę serwisu wysyłającego powiadomienia. Zalecane jest podawanie jego pełnej domenowej nazwy (FQDN). Dla serwisów z autentykacją podana nazwa FQDN musi pasować do nazwy domeny w podmiocie certyfikatu.

Przed otwarciem kanału należy zasubskrybować się na jego zdarzenia:

private void SubscribeToChannelEvents()
{
     httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(httpChannel_ChannelUriUpdated);
     httpChannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(httpChannel_HttpNotificationReceived);
     httpChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(httpChannel_ShellToastNotificationReceived);
     httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(httpChannel_ExceptionOccurred);
}

Po wywołaniu metody Open na obiekcie kanału, jego Uri jest przekazywane do aplikacji w delegacie zdarzenia ChannelUriUpdated. W przypadku wystąpienia błędu przy tworzeniu kanału lub w innych sytuacjach, wywołane zostanie zdarzenie ErrorOccurred. Przychodzące do aplikacji notyfikacje raw i toast obsługujemy w delegatach zdarzeń HttpNotificationReceived oraz ShellToastNotificationReceived:

void httpChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
    SubscribeToService();
    SubscribeToNotifications(); 
}

W delegacie zdarzenia ChannelUriUpdated powinniśmy zasubskrybować się w serwisie wysyłającym powiadomienia oraz na odbiór notyfikacji tile i toast.

W metodzie SubscribeToService przekazujemy adres kanału httpChannel.ChannelUri do serwisu w chmurze, z którego chcemy otrzymywać notyfikacje.  Do zalecanych praktyk można zaliczyć m.in. autentykację aplikacji w serwisie i szyfrowanie Uri kanału przed jego wysłaniem. Więcej dobrych praktyk znajdziesz w dokumentacji na stronie Setting up a Protocol to Communicate With Your Web Service for Windows Phone.

Subskrypcji na odbiór notyfikacji toast i tile dokonujemy za pomocą metod kanału BindToShellToast oraz BindToShellTile. W przypadku tej ostatniej metody mamy do dyspozycji jej dwie wersje. Jeśli w notyfikacji tile nie zamierzamy korzystać ze zdalnych zasobów dla obrazka w tle, to nie podajemy żadnych parametrów. Gdy używamy obrazków w sieci, należy podać listę dozwolonych domen. Przed dokonaniem subskrypcji na notyfikacje toast i tile zawsze należy sprawdzić, czy nie dokonano już wcześniej tych operacji (propercje kanału IsShellToastBound i IsShellTileBound):

private void SubscribeToNotifications()
{      
    if (!httpChannel.IsShellToastBound)
    {                    
        httpChannel.BindToShellToast();
    }
            
    if (!httpChannel.IsShellTileBound)
    {
        //httpChannel.BindToShellTile();
                
        Collection<Uri> ListOfAllowedDomains = new Collection<Uri> { new
        Uri("www.contoso.com") };
        httpChannel.BindToShellTile(ListOfAllowedDomains); 
    }  
}

Przy omawianiu implementacji serwisu i klienta dokonaliśmy pewnych uproszczeń dla zwiększenia czytelności prezentowanych treści. Kompletny praktyczny przykład znajdziesz w  Windows Phone 7 Training Course w ćwiczeniu Using Push Notifications.

Podsumowanie

Po przeczytaniu tego artykułu poznaliśmy notyfikacje push. Wiemy, na czym polega ich przewaga w stosunku do pollingu. Rozumiemy, w jaki sposób działają. Znamy ich rodzaje i możliwości. Wiemy, jakie kroki należy podjąć, aby stworzyć działające rozwiązanie.

 


          

Marcin Kruszyński

Absolwent wydziału EAIE Akademii Górniczo-Hutniczej w Krakowie na kierunku Informatyka. Technologiami Microsoft zajmuje się od sześciu lat. Pracuje w firmie ComArch, gdzie tworzy rozwiązania oparte na platformie .NET i Silverlight. Od dwóch lat jest architektem w centrum badawczo-rozwojowym. Wcześniej zajmował się utrzymaniem oraz rozwojem aplikacji webowych w systemie EDI dla dużych sieci handlowych. Interesuje się wieloma aspektami platformy .NET od pierwszej wersji. Obecnie specjalizuje się w implementacji bogatych interfejsów graficznych aplikacji w oparciu o Silverlight (desktop i mobilne) i WPF, których rozwój śledzi od początku ich istnienia. Sporo uwagi poświęca też platformie WCF RIA Services. Jest pasjonatem nowych trendów i technologii (zwłaszcza w wydaniach CTP i beta), których poznawaniem zajmuje się hobbystycznie i zawodowo. Prelegent grup społecznościowych. Prowadził warsztaty z Silverlight w Krakowie (KGD.NET) i Wrocławiu (PGS). Prezentował tworzenie aplikacji w Silverlight na Windows Phone 7 na Visual Studio 2010 Community Launch we Wrocławiu i Krakowie. Pełnił funkcję eksperta w strefie Ask The Expert (ATE) technologii Windows Phone na konferencji Microsoft Technology Summit (MTS) 2010.

Blogi: http://www.marcinkruszynski.blogspot.com, http://www.martinkruszynski.blogspot.com