2010-04-12 126 views
17

我們開發了一個iPhone應用程序,並且推送通知用於開發和臨時版本正常工作。但是當我們嘗試向我們的數據庫中的真實用戶設備發送推送通知時,我們得到了SSL連接重置,然後斷開了管道錯誤。我們認爲我們的數據庫中可能有太多設備(超過70000個),所以無法同時發送所有消息。所以我們嘗試將消息發送到1000個設備一次,但仍有100條消息出現「Broken pipe」錯誤。我們不確定這些郵件是否已發送。任何建議?獲取SSL嘗試進行推送通知時出現斷開管道錯誤

+0

我們有同樣的問題;儘管有100,000個用戶。 據我們所知,通知將達到前100個,但之後不會。我只能假設發送的通知存在限制(通過計數或時間)。 真的可以與某人確認嗎? – Wex 2010-05-19 16:48:49

回答

18

我們已經解決了這個問題。它因數據庫表中的無效標記而中斷。如果存在無效標記,則Apple apns服務將斷開與我們的連接。由於連接中斷,當您嘗試再次發送消息時,它會出現「Broken Pipe」錯誤。基本的解決方案是找到寫入管道是否成功,如果沒有,只需斷開連接,並在延遲後重新連接。

+11

我希望你已經解釋過你是如何編碼的 - Mona Jun 14 at 23:52 – Mona 2013-06-19 21:32:36

+0

通常,當我遍歷所有用戶的設備令牌時,如果其中任何一個失敗,它打破鏈式並顯示相同的錯誤,所有我們可以做的是用最近的設備令牌對用戶進行排序,並在我們的結束時檢查長度,之後它就起作用了。 謝謝你的回答幫助我!〜 – 2016-10-22 18:07:09

10

emagic是正確的,「無效管道」錯誤的一個原因可能來自無效標記。還有其他一些原因可能會發生。以下是來自Apple Technical Note TN2265

最常見的問題是無效的設備令牌。如果來自沙盒環境的令牌來自 ,例如當您在內部測試 開發版本時,則無法將其發送到生產推送 服務。每個推送環境將爲同一設備或計算機發出不同的令牌。如果您將設備令牌發送到錯誤的環境中,則推送服務會將該設備令牌視爲無效令牌,並丟棄該通知。

無效的設備令牌也可能表示用戶已從其設備或計算機中刪除了您的 應用程序。您應該至少每天檢查一次反饋 服務,以獲取不再有效的設備令牌 。

其他可能的問題可能會比256 個字節發送有效載荷時間越長,你的有效載荷可能無法正確格式化,或者您 JSON字典有不正確的語法。

偶爾斷開你的提供者空閒的時候是無關緊要的 ;只需重新建立連接並進行即可。如果推送服務器的一個 處於關閉狀態,則負載均衡機制將 透明地將您的新連接導向另一臺服務器,前提是您通過主機名而不是靜態IP地址連接 。

1

上EMAGIC的回答延伸,這是我的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()失敗時也是如此。我收到控制檯消息說它寫入失敗,但我從來沒有收到「發送有效負載錯誤」消息發送。你確定fwrite()實際上會拋出異常嗎? – othomas 2016-08-17 19:07:08

+0

嘗試刪除領先\從\例外.... – JoeGalind 2016-08-18 16:56:08

+0

試過,沒有區別。 catch塊永遠不會被調用。 – othomas 2016-08-19 20:57:14