Reputation: 883
for the past 3 days i have been trying to make things work with my php code and apns.
So far i'm able to deliver notifications (i only have one device so i don't know if this is working for multiple devices).
When i try to test sending one notification for 2 devices where the first is an device token invalid (invented by me) and the second is my device token, im unable to deliver the notification to my device... From what i read, when a notification is unreadable or erroneous, apns shuts the connection down and sends an error of 6 bytes long, where the 2nd byte (status_code) is the error type. If no error happens, im still unable to understand if apns send the status_code 0 (No errors encountered) or if it does not send anything at all.
So far i wasn't able to ever find this status_code, despite of following several codes found on internet.
CODE
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', '.\certif\ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Create the payload body
//file_put_contents('logs/debug_not.log', 'body'. "\n", FILE_APPEND);
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
//file_put_contents('logs/debug_not.log', 'json body'. "\n", FILE_APPEND);
$payload = json_encode($body);
$open = true;
foreach ($devices as $device) {
//file_put_contents('logs/debug_not.log', 'inicio ciclo'. "\n", FILE_APPEND);
if($open == true){
//file_put_contents('logs/debug_not.log', 'abrir ligacao'. "\n", FILE_APPEND);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp){
//file_put_contents('logs/debug_not.log', 'erro abrir ligacao'. "\n", FILE_APPEND);
throw new \Exception;
}
}
// Build the binary notification
//file_put_contents('logs/debug_not.log', 'criar payload'. "\n", FILE_APPEND);
$msg = chr(0) . pack('n', 32) . pack('H*', str_replace(' ', '', $device['token'])) . pack('n', strlen($payload)) . $payload;
// Send it to the server
//file_put_contents('logs/debug_not.log', 'enviar payload'. "\n", FILE_APPEND);
$result = fwrite($fp, $msg, strlen($msg));
stream_set_blocking ($fp, 0);
$errorResponse = @fread($apns, 6);
//if i var_dump($errorResponse) it gives me null/false all the time, no matter what
//this is my workaround for invalid device tokens-- its not working or at least is not send the valid tokens
if(!$result || !$fp)
{
//file_put_contents('logs/debug_not.log', 'erro na not '. chr($data["status_code"]). "\n", FILE_APPEND);
fclose($fp);
$open = true;
} else{
//file_put_contents('logs/debug_not.log', 'suc na not'. "\n", FILE_APPEND);
$open = false;
}
//file_put_contents('logs/debug_not.log', 'fim ciclo'. "\n", FILE_APPEND);
}
// Close the connection to the server
if($fp){
//file_put_contents('logs/debug_not.log', 'fechar connection'. "\n", FILE_APPEND);
fclose($fp);
}
fread on my connection gives null/false all the time, even when i receive my notification or i'm trying with a wrong token.
My logic for connect after error, seems to be not working.
can please someone help me??? i dont intend to use 3rd classes or code, would like to have a simple basic one working for an array of device tokens, even if there are some that apns gives error.
Thanks everyone.
Upvotes: 2
Views: 2442
Reputation: 392
You have made your connection as $fp = stream_socket_client ......
and you are trying to $errorResponse = @fread($apns, 6);
which will never give you any output as $apns is not defined.
Rather you should do this :
$errorResponse = @fread($fp, 6);
and your code will work fine
Upvotes: 6
Reputation: 53830
If you receive an error (most likely in your case because your invented device token does not exist on Apple's servers for your app), then an error message is returned just before the connection is closed. If the message is successful, there is no response, but the connection remains open.
Here's how you could handle this:
Keep track of your last successful message. You could always follow up a series of messages by sending your own device a message just to prevent any false positives.
You might want to check out the source code for EasyAPNS, which is an open source PHP implementation of this. Also, you can read the details in Apple's documentation: Provider Communication with Apple Push Notification Service
Upvotes: 1