2010-04-12 12 views
17

Opracowujemy aplikację na telefon iPhone i powiadamiamy o wypychaniu dla wersji rozwojowej i wersji ad hoc działającej prawidłowo. Ale kiedy próbujemy wysłać powiadomienie push do rzeczywistych urządzeń użytkownika w naszej bazie danych, otrzymaliśmy reset połączenia SSL, a następnie błąd potoku przerwanego. Wydaje nam się, że w naszej bazie danych jest zbyt wiele urządzeń (ponad 70000), więc nie udało się wysłać wszystkich wiadomości w tym samym czasie. Dlatego próbujemy wysyłać wiadomości do 1000 urządzeń tylko raz, ale nadal otrzymujemy błąd "Broken pipe" dla około 100 wiadomości. I nie jesteśmy pewni, czy wiadomości zostały wysłane. Jakieś sugestie?Uzyskiwanie błędu protokołu SSL przerwanego przy próbie wprowadzenia powiadomienia push

+0

Mamy ten sam problem; choć z 100 000 użytkowników. O ile możemy powiedzieć, powiadomienie dotrze do pierwszych 100-tych, ale nie później. Mogę tylko założyć, że istnieje limit (według liczby lub czasu) wysyłanych powiadomień. Czy naprawdę można to zrobić z kimś, aby to potwierdzić? – Wex

Odpowiedz

18

Rozwiązaliśmy ten problem. Jest zepsuty z powodu nieprawidłowych tokenów w naszej tabeli bazy danych. Usługa Apple Apns rozłączy nas, jeśli pojawi się nieprawidłowy token. Ponieważ połączenie jest zepsute, przy próbie ponownego wysłania wiadomości pojawi się błąd "Broken Pipe". Podstawowym rozwiązaniem jest ustalenie, czy zapisywanie na rurze zakończyło się sukcesem, jeśli nie, wystarczy odłączyć i ponownie nawiązać połączenie po pewnym opóźnieniu.

+11

Szkoda, że ​​nie wyjaśniłeś, w jaki sposób to zakodowałeś - Mona Jun 14 o 23:52 – Mona

+0

Zwykle zdarza się, gdy przechodzę przez token urządzenia użytkownika i jeśli którykolwiek z nich się nie powiedzie, to łamie rodzaj łańcucha i pokazuje ten sam błąd, wszystko co mamy można zrobić to posortować użytkownika za pomocą najnowszego tokenu urządzenia i sprawdzić długość na naszym końcu, po czym zadziałało. Dziękuję, że odpowiedź pomogła mi!~ –

10

Emagic jest poprawny, jeden z powodów błędu "zerwanej rury" może wystąpić z nieprawidłowych tokenów. Jest kilka innych powodów, które mogą wystąpić. Poniżej przedstawiono numer Apple Technical Note TN2265:

Najczęstszym problemem jest nieprawidłowy token urządzenia. Jeśli token pochodził z środowiska piaskownicy , na przykład podczas testowania kompilacji rozwojowej , nie można wysłać go do usługi pchania produkcyjnego . Każde środowisko push wystawi inny token dla tego samego urządzenia lub komputera. Jeśli wyślesz token urządzenia do niewłaściwego środowiska , usługa push zobaczy, że jako nieważny token i odrzuci powiadomienie.

Nieprawidłowy token urządzenia może również oznaczać, że użytkownik usunął aplikację ze swojego urządzenia lub komputera. Należy sprawdzać informację zwrotną pod numerem co najmniej raz dziennie, aby ważne tokeny urządzeń, które nie są już ważne.

Innymi możliwymi problemami może być wysłanie ładunku dłuższego niż 256 bajtów, Twój ładunek może nie być poprawnie sformatowany lub Twój słownik JSON ma niepoprawną składnię.

Okazjonalne rozłączenie w czasie, gdy Twój dostawca jest bezczynny, nie ma nic przeciwko temu, aby być ; po prostu przywróć połączenie i kontynuuj. Jeśli jeden serwer serwera push zostanie wyłączony, mechanizm równoważenia obciążenia przejdzie w sposób przezroczysty na nowe połączenie z serwerem, zakładając, że łączy się za pomocą nazwy hosta, a nie statycznego adresu IP.

1

Rozszerzenie na odpowiedź EMAGIC, jest to mój kod php snipplet:

private $fp; 

private function connect(){ 
    $apnsHost  = 'gateway.push.apple.com'; 
    $apnsCert  = 'certs/cert.pem'; 
    $apnsPort  = 2195; 
    $pass   = "blah"; 
    $streamContext = stream_context_create(); 

    stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert); 
    stream_context_set_option($streamContext, 'ssl', 'passphrase', $pass); 
    $this->fp = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContext); 
    if (!$this->fp) return("Failed to connect: $err $errstr<br>"); 
    echo 'Connected to APNS<hr />'; 
    } 

private function send(){ 
    $this->connect(); 
    foreach($pushes as $push) { 
    $payload['aps'] = array('alert' => $push->text, 'badge' => 0, 'sound' => 'default'); 
    $payload2 = json_encode($payload); 
    $msg = chr(0) . pack('n', 32) . pack('H*', $push->token) . pack('n', strlen($payload2)) . $payload2; 
    try { 
     $result = fwrite($this->fp, $msg, strlen($msg)); 
    } 
    catch (\Exception $e) { 
     fclose($this->fp); 
     echo('Error sending payload: ' . $e->getMessage()); 
     sleep(5); 
     $this->connect(); 
    } 
    } 
} 
+0

Próbuję użyć tego, ale próba/catch nie wydaje się być wyzwalana, nawet gdy fwrite() nie powiedzie się. Otrzymuję komunikaty konsoli informujące, że nie udało się napisać, ale nigdy nie otrzymałem wiadomości "Błąd wysyłania ładunku" do wysłania. Czy jesteś pewien, że fwrite() faktycznie rzuca wyjątki? – othomas

+0

Spróbuj usunąć wiodącą \ z \ Wyjątek .... – JoeGalind

+0

Wypróbowany, nie ma znaczenia. Blok catch nigdy nie jest wywoływany. – othomas

Powiązane problemy