We develop an iPhone app, and have push notification for development and ad hoc version working properly. But when we try to send push notification to real user devices in our database, we got SSL connection reset, then Broken pipe error. We think maybe there are too many devices in our database (more than 70000), so it is failed to send all messages at the same time. So we try to send messages to 1000 devices once, but still got this "Broken pipe" error for around 100 messages. And we are not sure whether the messages have been send. Any suggestion?
We have solved this problem. It is broken due to invalid tokens in our database table.And apple apns service will disconnect us if there is an invalid token. Since the connection is broken, it will have "Broken Pipe" error when you try to send messages again. Basic solution is to find whether writing to pipe is successful, if not, just disconnect and reconnect again after some delay.
emagic is correct, one reason for the "broken pipe" error can occur from invalid tokens. There are a few other reasons it can occur too. The following is from Apple Technical Note TN2265:
The most common problem is an invalid device token. If the token came from the sandbox environment, such as when you are testing a development build in house, you can't send it to the production push service. Each push environment will issue a different token for the same device or computer. If you do send a device token to the wrong environment, the push service will see that as an invalid token and discard the notification.
An invalid device token can also mean that the user has deleted your app from their device or computer. You should check the feedback service at least once a day for device tokens that are no longer valid.
Other possible issues might be sending a payload longer than 256 bytes, your payload might not be formatted correctly, or perhaps your JSON dictionary has incorrect syntax.
An occasional disconnect while your provider is idle is nothing to be concerned about; just re-establish the connection and carry on. If one of the push servers is down, the load balancing mechanism will transparently direct your new connection to another server assuming you connect by hostname and not by static IP address.
Extending on emagic's answer, this is my php code 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();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With