0

Apple's docs say that:

"If you send a notification and APNs finds the notification malformed or otherwise unintelligible, it returns an error-response packet prior to disconnecting. (If there is no error, APNs doesn’t return anything.) Figure 5-3 depicts the format of the error-response packet."

This leads me to believe that the only reason that APNS would not send something back is if what I sent them was in the correct format. However when I try to fread for their response I get a string of 0 length and when unpacked becomes null, which I assume means nothing has been written back to me.

I the stream was opened by stream_socket_client() and did not return false or throw an exception. I know that my fwrite successfully wrote 154 bytes to that stream as well. Why would there be no response from Apple?

Here is the code for connecting to APNS:

function openConnection() {
    $streamContext = stream_context_create();
    stream_context_set_option($streamContext, 'ssl', 'local_cert', $this->APNS_CERT);
    stream_context_set_option($streamContext, 'ssl', 'passphrase', $this->Password);
    $apns = stream_socket_client('ssl://' . $this -> APNS_HOST . ':' . $this -> APNS_PORT, $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
    return $apns;
}

Then, in the next method after calling openConnection:

//open the connection to use with apple.
$apns = $this->openConnection();

$alert = $message['alert'];
$badge = $message['badge'];
$deviceToken = $message['deviceToken'];

$payload['aps'] = array(
    'alert' => $message['alert'],
    'badge' => $message['badge'],
    'sound' => $message['sound']
);

if ($message['extraPayload'] != null) {
    $payload['acme'] = $message['extraPayload'];
}

$encodedString = json_encode($payload);

//create message
$apnsMessage = chr(1) . pack("N", $message['identifier']) . pack("N", $message['expire']) . pack("n", 32) . pack('H*', str_replace(' ', '', $message['deviceToken'])) . pack("n",strlen($encodedString)) . $encodedString;

$write = fwrite($apns, $apnsMessage);
echo $write;
//the echo was just to see if it wrote.

if (!$apns) {
    socket_close($apns);
    fclose($apns);

    echo "connection to APNS was lost.";
}


//look for changes. $null=null because some bug doesn't just let you pass null.
$null = null;
$changedStreams = stream_select($streamArray, $null, $null, 0, 1000000);

//check if it is actually false
if ($changedStreams === false) {
    //close stream when done.
    socket_close($apns);
    fclose($apns);

    echo "No response from APNs";
} elseif ($changedStreams > 0) {
//then check if what they sent back is an error and grab the error packet
$responseBinary = fread($apns, 6);
var_dump($responseBinary);

//check that it's the right thing
if ($responseBinary != false || strlen($responseBinary) == 6) {
    //convert it from it's binary stream state and print.
    $response = unpack('Ccommand/Cstatus_code/Nidentifier', $responseBinary);
    var_dump($response);

    //close stream when done.
    socket_close($apns);
    fclose($apns);
    }
} else {
    echo "Apple failed to respond, message was not sent.";
}

The var_dump at the end is NULL.

Edit:

Turns out it was an error with conflicting credentials. It was solved by creating a new pem file.

eloibm
  • 899
  • 2
  • 11
  • 27
Joseph Waelchli
  • 60
  • 1
  • 10
  • http://stackoverflow.com/questions/2293155/apple-push-notification-service-apns-notifications-not-arriving?rq=1 – KevinDTimm Nov 02 '12 at 21:25
  • In response to the other question you posted, I am not the developer working on the app side of this, so i don't know the particulars, but he says it is an ad-hoc version of the app and we are not using sandbox which I believe is correct. – Joseph Waelchli Nov 02 '12 at 21:51
  • note that the following says that fread cannot be used for APNs (http://stackoverflow.com/questions/1278834/php-technique-to-query-the-apns-feedback-server?rq=1) – KevinDTimm Nov 02 '12 at 22:28
  • Thanks for that, I have altered my code slightly although it did not change the NULL responses. I'm going to speak with the ios developer again and double check the pem, app versions etc. – Joseph Waelchli Nov 02 '12 at 22:53
  • 1
    fyi APNS sandbox server will not return any data upon error. Just shutdown the connection. Try use production server. – est Apr 26 '14 at 06:53

1 Answers1

2

From that page:

You should regularly connect with the feedback web server and fetch the current list of those devices that have repeatedly reported failed-delivery attempts. Then you should cease sending notifications to the devices associated with those applications. See “The Feedback Service” for more information.

Feedback Service

Access to the feedback service takes place through a binary interface similar to that used for sending push notifications. You access the production feedback service via feedback.push.apple.com, port 2196; you access the sandbox feedback service via feedback.sandbox.push.apple.com, port 2196. As with the binary interface for push notifications, you must use TLS (or SSL) to establish a secured communications channel. The SSL certificate required for these connections is the same one that is provisioned for sending notifications. To establish a trusted provider identity, you should present this certificate to APNs at connection time using peer-to-peer authentication.

KevinDTimm
  • 14,226
  • 3
  • 42
  • 60
  • Isn't that service just for deleting device tokens that have expired due to the user deleting the application? the device token I am attempting to use was given to the web service only 2 days prior. – Joseph Waelchli Nov 02 '12 at 21:20
  • As far as I can tell, the only way to learn why something is failing is the feedback service – KevinDTimm Nov 02 '12 at 21:22
  • Alright, well thanks for the reply. I'm going to go try that and then post the results. – Joseph Waelchli Nov 02 '12 at 21:25
  • Perhaps I'm doing my fread wrong, as that also produced an empty string. I'll edit my original post to include some code. – Joseph Waelchli Nov 02 '12 at 21:35
  • Hey, just wanted to let you know we created a new pem file and now the script is working fine in it's original state. I guess this error was just cause by confusion. – Joseph Waelchli Nov 06 '12 at 02:13