2009-08-14 30 views
28

Czy ktoś może wyjaśnić, co APN (Apple Push Notification) chce, o ile zapytasz?Technika PHP do wysyłania zapytań do serwera opinii APN

Dokumenty mówią, że rozpoczyna wysyłanie zaraz po nawiązaniu połączenia. Czy to oznacza, że ​​nie robię na nim fread()?

Oto mój obecny kod, aby spróbować go przeczytać. NIE umieściłem fread() w pętli, ponieważ nie wiem, co oznacza odpowiedź "nie więcej rekordów do odczytu" i nie chciałem nieskończonej pętli na moim serwerze.

<?php 
$apnsCert = 'HOHRO-prod.pem'; 

$streamContext = stream_context_create(); 
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert); 
stream_context_set_option($streamContext, 'ssl', 'verify_peer', false); 

$apns = stream_socket_client('ssl://feedback.push.apple.com:2196', $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext); 

echo 'error=' . $error; 
echo 'errorString=' . $errorString; 


$result = fread($apns, 38); 
echo 'result=' . $result; 


fclose($apns); 
?> 

Do tej pory wszystko, co otrzymuję, jest zerową odpowiedzią. Nie ma błędów, więc jest połączenie.

Nie wiem, czy odpowiedź zerowa oznacza brak danych, czy mój fread() jest niewłaściwy sposób to zrobić.

Dzięki

+0

Dziś odkryłem, że fread() nie będzie działać, ponieważ APN zwrotne wysyła dane na śmieci do rzeczywistej informacji zwrotnej. To powoduje, że fread się nie powiedzie, ponieważ odczytuje puste dane. Jak wspomnia o gw1921, musisz włączyć pętlę feof(), aż do strlen (fread ($ apns, 38)). Od tego momentu otrzymasz prawidłową informację zwrotną. Następnie rozpakuj dane, tak jak sugerował Nick B poniżej. (Kolejny paskudny błąd: odinstalowana aplikacja nie będzie generować informacji zwrotnej, chyba że masz inną aplikację na urządzeniu z tym samym środowiskiem aplikacji, więc potrzebujesz 2 aplikacji piaskownicy obsługujących naciśnięcie przycisku w urządzeniu, aby odinstalować jedną z nich.) – brack

+0

Nawet mam podobny kod i ja też dostaję zerowy od strachu. Nie jestem pewien, czy mój kod działa, a APNS wysyła NULL odpowiedź lub po prostu czegoś brakuje. Jestem pewien, że moje połączenie z APNS zakończyło się sukcesem. Zainstalowałem moją aplikację na około 5-10 urządzeniach i wysłałem kilka alertów, a następnie odinstalowałem aplikację z kilku i ponownie wysłałem ostrzeżenia, aby serwer opinii APNS dał nam znać, że nie udało się dostarczyć na kilku urządzeniach. Nie mam nic innego niż puste w fiddle() :-(Jeśli zrobiłeś coś innego i sprawiłeś, że działaj, proszę daj mi znać – Anish

+0

Czy użyłeś "pushutil"? Kiedy to odkryjesz, jest to szybszy sposób aby sprawdzić serwer opinii To narzędzie Mac OS X, które kompilujesz, a następnie uruchamiasz z wiersza poleceń Uniksa Google Erica Sadun - jest na swojej stronie pod Push. –

Odpowiedz

1

Mam roztwór z forum jabłkowego i to do rozwoju. Wypróbuj to również do produkcji.

„No, jak głupi, jak się wydaje, znalazłem rozwiązanie:

Tworzenie obojętne identyfikator aplikacji w portalu programu, włączyć powiadomienia Push rozwój na go utworzyć i pobrać powiązany profil zastrzegania utworzyć nowy xcode project i wywołaj metodę registerForRemoteNotificationTypes na starcie Zainstaluj na tym urządzeniu sztuczną aplikację W tym momencie powinieneś mieć uruchomione na urządzeniu dwie aplikacje DEVELOPMENT: oryginalną aplikację i fałszywą aplikację. powiadomień Odinstaluj oryginalną aplikację i spróbuj wysłać powiadomienie wypychane do tej aplikacji Wywołaj serię opinii vice, a ty powinieneś otrzymać dane z powrotem. "

2

Ten kod wygląda dobrze, jednak musisz zapętlić i sprawdzić koniec strumienia, aby odczytać wszystkie kody urządzeń.

while (!feof($apns)) { 
     $devcon = fread($apns, 38); 
} 

Jednak moim problemem jest faktyczne rozpakowanie danych. Czy ktoś wie, jak rozpakować dane binarne, które właśnie przeczytałeś, aby uzyskać rzeczywisty identyfikator urządzenia (jako ciąg) wraz ze znacznikiem czasowym itp.?

+1

Myślę, że to jest właściwy pomysł - $ array = unpack ("NnH32", wynik $); $ feedbackTime = $ row [0]; $ feedbackLen = $ row [1]; $ feedbackUDID = $ row [2]; To rozpakuje 38 bajtów wysłanych przez serwer opinii. Jednak 32-bitowa wartość daty jest w porządku sieciowym lub big-endian. Jeśli ktoś może dostarczyć funkcję PHP, która odwróci to 4 bajty do porządku Intela (little-endian), myślę, że mamy rozwiązanie. UWAGA: rzeczywisty identyfikator UDID jest ciągiem znaków i NIE musi mieć odwróconej kolejności. –

+0

Czy to dobrze? --------- /* Konwersja pływaka od HostOrder z siecią zamówienia */ funkcji FToN ($ val) { $ a = unpack ("I", paczka ("F", $ val)); pakiet zwrotny ("N", $ a [1]); } /* Konwersja pływaka od Network Zakonu HostOrder */ funkcja NToF ($ val) { $ a = rozpakować ("N", $ val); $ b = rozpakuj ("f", pakiet ("I", $ a [1])); return $ b [1]; } – strange

0

To w końcu zadziałało dla mnie.

$arr = unpack("H*", $devconts); 
$rawhex = trim(implode("", $arr)); 

$feedbackTime = hexdec(substr($rawhex, 0, 8)); 
$feedbackDate = date('Y-m-d H:i', $feedbackTime); 
$feedbackLen = hexdec(substr($rawhex, 8, 4)); 
$feedbackDeviceToken = substr($rawhex, 12, 64); 

A następnie po prostu sprawdź token urządzenia przed sygnaturą czasową!

+0

Działa to świetnie, gw1921. Przechowuję $ feedbackDate w kolumnie SQL na teraz.Jakiego rodzaju danych powinna mieć kolumna? Ustawiłem ją na Integer i to daje mi "2009". Pozostałe 2 kolumny, długość i token działają GREAT !! Dzięki –

70

Oto wielki haczyka który mylić mnie, kiedy pierwszy raz próbował podłączenia: serwery feedback APNS powrócić tylko żetony urządzeń, które „wygasły” od ostatniego wniosku zwrotnego. Co oznacza, że ​​przez większość czasu otrzymujesz NULL odpowiedź, chyba że masz już do czynienia z dużą liczbą użytkowników Twojej aplikacji.

Pamiętaj więc, aby przechowywać wygasłe tokeny urządzeń na dysku lub db, ponieważ po zapytaniu zwrotnym zniknęły na dobre. To sprawia, że ​​testowanie bólu jest co najmniej!

Oto pełna funkcja sprowadzić tokeny urządzenie z serwerów zwrotnych APN (wielkie dzięki do odpowiedzi powyżej pomaga mi je połączyć):

function send_feedback_request() { 
    //connect to the APNS feedback servers 
    //make sure you're using the right dev/production server & cert combo! 
    $stream_context = stream_context_create(); 
    stream_context_set_option($stream_context, 'ssl', 'local_cert', '/path/to/my/cert.pem'); 
    $apns = stream_socket_client('ssl://feedback.push.apple.com:2196', $errcode, $errstr, 60, STREAM_CLIENT_CONNECT, $stream_context); 
    if(!$apns) { 
     echo "ERROR $errcode: $errstr\n"; 
     return; 
    } 


    $feedback_tokens = array(); 
    //and read the data on the connection: 
    while(!feof($apns)) { 
     $data = fread($apns, 38); 
     if(strlen($data)) { 
      $feedback_tokens[] = unpack("N1timestamp/n1length/H*devtoken", $data); 
     } 
    } 
    fclose($apns); 
    return $feedback_tokens; 
} 

Jeśli wszystko jest dobrze, wartości zwrotu z ta funkcja będzie wyglądała mniej więcej tak (przez print_r()):

Array 
(
    Array 
    (
     [timestamp] => 1266604759 
     [length] => 32 
     [devtoken] => abc1234..............etcetc 
    ), 
    Array 
    (
     [timestamp] => 1266604922 
     [length] => 32 
     [devtoken] => def56789..............etcetc 
    ), 
) 
+0

Dziękujemy za to eleganckie rozwiązanie. Teraz wystarczy wiedzieć, jak porównać znacznik czasu zwrócony przez powyższy kod zwrotny do znacznika czasu, który zapisałem w mojej bazie danych, co oczywiście stanowi ostatni czas, w którym urządzenie wysłało mi token. Czy wystarczy porównać liczbę całkowitą? Czy muszę przekonwertować sygnatury czasowe, aby poprawić endianizm? –

+0

Ta odpowiedź powinna być przyjętym rozwiązaniem, IMO. W zasadzie to robię i działa idealnie. Jeśli nadal nie widzisz danych zwrotnych za pomocą tej metody, sprawdź, czy masz włączoną inną aplikację na urządzeniu w/push, która zgłasza to samo środowisko aplikacji, co odinstalowana aplikacja. Johnny - jeśli chodzi o znacznik czasu, po rozpakowaniu go tak, jak w postu Nicka, możesz porównać liczbę całkowitą. – brack

+1

W takim przypadku nie otrzymam odpowiedzi z serwera opinii? Moje powiadomienia sprawdzają się dobrze (jak mogę powiedzieć z dzienników), ale z jakiegoś powodu nigdy nie otrzymuję żadnych powiadomień na urządzeniu! – lostInTransit