2010-04-12 7 views
17

iPhone 앱을 개발하고 개발 및 임시 버전에 대한 푸시 알림이 제대로 작동합니다. 그러나 데이터베이스의 실제 사용자 장치에 푸시 알림을 보내려고하면 SSL 연결이 재설정 된 다음 깨진 파이프 오류가 발생합니다. 우리 데이터베이스 (70000 개 이상)에 너무 많은 장치가있는 것 같아서 동시에 모든 메시지를 보내지 못했습니다. 그래서 우리는 한번 1000 개의 장치로 메시지를 보내려고하지만 약 100 개의 메시지에 대해이 "브로큰 파이프"오류가 계속 발생합니다. 그리고 우리는 메시지가 전송되었는지 확실하지 않습니다. 어떠한 제안?푸시 알림을 만들려고 할 때 SSL이 깨졌습니다.

+0

; 10 만 명의 사용자가 있습니다. 우리가 알 수있는 한 알림은 첫 번째 100 개 또는 그 이후에 도달하지만 그 이후에는 도달하지 않을 것이라고 알릴 수 있습니다. 나는 전송 된 통지에 한도 (횟수 또는 시간)가 있다고 가정 할 수 있습니다. 정말이를 확인하는 사람과 함께 할 수 있습니까? – Wex

답변

18

이 문제를 해결했습니다. 데이터베이스 테이블의 유효하지 않은 토큰으로 인해 손상되었습니다. 사과 apns 서비스는 유효하지 않은 토큰이있는 경우 연결을 끊습니다. 연결이 끊어지기 때문에 메시지를 다시 보내려고하면 "깨진 파이프"오류가 발생합니다. 기본적인 해결책은 파이프에 쓰는 것이 성공했는지 아닌지 확인하는 것입니다. 그렇지 않은 경우 약간의 지연 후에 연결을 끊었다가 다시 연결하십시오.

+11

내가 어떻게 코드화했는지 설명했으면 좋겠다. Mona Jun 14 at 23:52 – Mona

+0

보통 모든 사용자의 장치 토큰을 통해 루프를 돌릴 때 일어난다. 만약 실패하면 체인 종류가 깨지고 같은 오류가 발생한다. 최근 장치 토큰을 가진 사용자를 분류하고 우리의 끝에 길이를 검사하는 것은 할 수있다, 그것은 그 후에 일했다. 답변 해 주셔서 감사합니다.~ –

10

emagic이 정확하면 유효하지 않은 토큰으로 인해 "broken pipe"오류가 발생할 수 있습니다. 그것이 발생할 수있는 몇 가지 다른 이유가 있습니다. 다음은 Apple Technical Note TN2265에서입니다.

가장 일반적인 문제는 잘못된 장치 토큰입니다. 토큰이 개발 빌드를 집에서 테스트하는 경우와 같이 샌드 박스 환경에서 으로 제공된 경우 프로덕션 푸시 서비스로 보낼 수 없습니다. 각 푸시 환경은 동일한 장치 또는 컴퓨터에 대해 다른 토큰을 발행합니다. 기기 토큰을 잘못된 환경으로 보내면 푸시 서비스에 잘못된 토큰으로 표시되고 알림을 무시합니다.

잘못된 기기 토큰은 사용자가 기기 또는 컴퓨터에서 앱을 삭제했음을 의미 할 수도 있습니다. 유효하지 않은 장치 토큰에 대해 적어도 하루에 한 번 피드백 서비스를 확인해야합니다.

다른 가능한 문제는 256 바이트보다 긴 페이로드를 보내거나 페이로드가 올바르게 포맷되지 않았거나 JSON 사전의 구문이 잘못되었을 수 있습니다.

제공자가 유휴 상태 일 때 가끔씩 연결이 끊기는 경우 과 관련이 없습니다. 연결을 다시 설정하고 계속 수행하십시오. 고정 서버의 이 다운 된 경우 을 정적 IP 주소가 아닌 호스트 이름으로 연결한다고 가정하면 부하 분산 메커니즘은 이 다른 서버로 투명하게 연결되도록합니다. emagic의 대답에 확장

1

이 내 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

나는 이것을 사용하려고 노력하고 있지만 try/catch는 fwrite()가 실패하더라도 트리거되지 않는 것처럼 보입니다. 나는 콘솔 메시지를 쓰지 못했다는 말을 듣지 만 보내려는 "Error sending payload"메시지를받지 못한다. fwrite()가 실제로 예외를 던질 것이라고 확신합니까? – othomas

+0

선도 \ \ 예외 \ ....를 제거해보십시오. – JoeGalind

+0

시도해 보니 차이가 없습니다. catch 블록은 호출되지 않습니다. – othomas

관련 문제