Push Notification i PHP – step by step

Ponieważ Windows Phone 7 nie pozwala na wykonywanie operacji w tle, jesteśmy zmuszeni do przeniesienia pewnych zadań na serwer. Poza tym cykl życia aplikacji w tym systemie sprawia, że użytkownik musi oczekiwać na wiadomość zwrotną tak aby nasz program był cały czas aktywny. Aby ominąć te niedogodności (zarówno dla programisty jak i użytkownika) należy posłużyć się mechanizmem notyfikacji PUSH. W sieci nie trudno znaleźć artykuły na ten temat. Na samym MSDN umieszczony jest kod, zarówno ten po stronie serwera jak i klienta, który można żywcem skopiować i wkleić do swojej aplikacji. Problem dla programisty .Net zaczyna się w sytuacji, gdy do dyspozycji mamy tylko serwer z PHP. W tym wpisie przedstawię jak krok po kroku zbudować i połączyć aplikację Windows Phone z Web serwisem w PHP.

Jeżeli Push Notification jest dla Ciebie nowym pojęciem, zachęcam do zapoznania się z nagraniem na Channel 9 (w języku polskim). W dalszej części artykułu zakładam, że potrafisz sam zaimplementować stronę kliencką w C#. Kompletny kod źródłowy i C# i PHP udostępniam do pobrania.

Ogólny zarys

Zagadnienie omówię na przykładzie prostego systemu informacyjnego. Klienci zgłaszają chęć otrzymywania wiadomości. Następnie z serwera „spływa” informacja do wszystkich zainteresowanych. Wykorzystamy 2 aplikacje w Windows Phone oraz 2 web serwisy. Pierwszy program o nazwie Newsletter Client będzie umożliwiał dokonanie subskrypcji oraz wyświetlał stronę internetową odebraną od MPNS. Drugi o nazwie Newsletter wykorzystamy do wpisywania adresu strony internetowej, która zostanie wysłana na serwer, a później poprzez MPNS do klienta.

Potrzebujemy również bazy danych MySQL z jedną tabelą, w której będziemy przechowywać subskrypcje.

Baza danych

Najpierw zajmiemy się stworzeniem bazy danych. Jak wcześniej wspomniałem  będzie to MySql. Nie umieszcze tu żadnego kodu, wszystko można wykonać przy pomocy phpMyAdmin. Bazę nazwijmy wp7test, do tego stwórzmy użytkownika o odpowiednich uprawnieniach na tej bazie o nazwie wp7 i haśle test. W warunkach testowych użytkownik może posiadać wszystkie uprawnienia. Natomiast w projekcie końcowym nie powinien on posiadać takich uprawnień jak tworzenie czy usuwanie tabel, a zwłaszcza do wykonywania DROP DATABASE ;-). Wystarczy INSERT i SELECT.

W naszej bazie stwórzmy tabelę o nazwie subscribers o dwóch polach: id (int, auto increment) i uri (varchar). W uri będziemy przechowywać adresy odebrane po rejestracji w MPNS.

Aplikacja Newsletter Client i odpowiedni webservice

Działanie aplikacji ogranicza się do wysłania channelUri otrzymanego z MPNS na serwer. Dlatego web service będzie posiadał tylko jedną usługę – subscribe – z parametrem uri.

function subscribe($uri) {
    // serwer, nazwa użytkownika i hasło
    $connect = mysql_connect("localhost", "wp7", "test");

    if ($connect) {

        // wybieramy bazę danych
        if(mysql_select_db("wp7test", $connect)) {
            // wstawiamy uri do tabeli subscribers
            mysql_insert('subscribers', array(
                'uri' => $uri,
            ));
            mysql_close($connect);
            return true;
        }

        mysql_close($connect);
    }
    return false;
}

Jak widzimy subscribe łączy się z bazą MySQL na localhost (jeżeli baza danych jest na tym samym serwerze co plik z serwisem). Wstawiamy otrzymany uri do tabeli subscribers. Metoda mysql_insert nie jest wbudowana, można ją znaleźć w kodzie źródłowym na końcu artykułu. Kolejna uwaga odnośnie bezpieczeństwa. Nazwa użytkownika i hasło powinny być trzymane poza plikiem z serwisem. Można to zrobić definiując odpowiednie stałe dla hasła i loginu w oddzielnym pliku php umieszczonym poza katalogiem public_html.

Teraz musimy zarejestrować metodę subscribe, tak aby była widziana przez aplikacje klienckie łączące się z naszym serwisem. W NuSoap wygląda to następująco:

$server->register(
'subscribe', // nazwa metody z php
array('uri' => 'xsd:string'), // tablica parametrów
array('return' =>'xsd:boolean'), // typ wartości zwracanej
'urn:wp7wsdl',
'urn:wp7wsdl#subscribe',
'rpc',
'literal', // encoded nie działa z silverlightem
'Subscribe' // opcjonalny opis metody uwzględniony w WSDL
);

To tyle, jeżeli chodzi o najważniejsze fragmenty pierwszego serwisu. Aby połączyć się z nim w kodzie C# potrzebujemy przede wszystkim jego adresu. Załóżmy, że serwis znajduje się w pliku o nazwie wp7.php, w głównym katalogu serwera na mojadomena.pl. Wtedy dodając referencje w Visual Studio (Add service reference) wpisujemy:

http://www.mojadomena.pl/wp7.php?wsdl

Wywoływanie odpowiednich metod przebiega dokładnie tak samo jak w przypadku serwisów WCF. Dodam jeszcze, że w Windows Phone (i w Silverlight) wszystkie metody wywoływane są asynchronicznie.

Aplikacja Newsletter i serwis komunikujący się z MPNS

Teraz czeka nas nieco trudniejsze zadanie. Sama aplikacja Windows Phone jest banalna. Wywołuje ona tylko jedną metodę z nowego serwisu, przekazując adres www wybranej przez nas strony.

Web serwis ponownie będzie składał się z jednej usługi:

function send_news($url) {
	// serwer, nazwa użytkownika i hasło
	$connect = mysql_connect("localhost", "wp7", "test");

	if ($connect) {

		// wybieramy bazę danych
		if(mysql_select_db("wp7test", $connect)) {

		   $query_result = mysql_query("SELECT * FROM subscribers");

		   while($row = mysql_fetch_array($query_result)) {

		      $push = new WindowsPhonePushClient($row['uri']);
		      $push->send_toast('News', $url, "/NewsPage.xaml?url=" . $url);
		   };

		   return true;
		}

		mysql_close($connect);
	}
	return false;
}

W linii 10 pobieramy informacje o wszystkich subskrybentach. W pętli while wysyłamy informacje do MPNS poprzez obiekt klasy WindowsPhonePushClient. W konstruktorze przyjmuje URI kanału zarejestrowanego dla danego telefonu. Metoda send_toast przyjmuje kolejno Text1, Text2 i Param z zapisu XML dla notyfikacji toast. Jako wiadomość zwrotną otrzymamy podobnie jak w .Net tablice / słownik z X-SubscriptionStatus, X-NotificationStatus i X-DeviceConnectionStatus.

Taki zapis w Param: /NewsPage.xaml?url=” . $url sprawi, że kliknięcie na notyfikacje toast w telefonie przeniesie nas do aplikacji klienckiej na stronę NewsPage.xaml, z parametrem url (zawierający wysłany przez nas adres www) w NavigationContext. Można to wykorzystać następująco:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    WebBrowser.Navigate(new Uri("http://" + NavigationContext.QueryString["url"]));
}

Klasa WindowsPhonePushClient nie została napisana przeze mnie. Można ją znaleźć tutaj. Jest tam kilka błędów i autor nie przewidział np. opcji Param w notyfikacji toast. Dokonałem kilku poprawek i już bez problemu można z niej korzystać. Aby kod zadziałał, serwer musi obsługiwać rozszerzenie php_curl! WampServer, z którego korzystam do testów, domyślnie ma to rozszerzenie wyłączone.

Na koniec

To wszystko jeżeli chodzi o kod w PHP. Zaznaczam, że moja znajomość tego języka ogranicza się do pisania web serwisów komunikujących się z baza w MySQL. Także proszę nie pytać o szczegóły. Kod w C# nie zawiera niczego szczególnego poza standardową obsługą notyfikacji i web serwisów.

{filelink=3}

Share

Jedna myśl nt. „Push Notification i PHP – step by step

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Spam protection by WP Captcha-Free