2010-04-12 127 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