APNS close connection after sending 507 push message - php

I have submit my app to apple store and now I want to send APNS to the users .
I want to send 7000 push messages through this php code from my desktop:
<?php
// Put your private key's passphrase here:
$passphrase = '*****';
// Put your alert message here:
$message = 'text here';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS</br>' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
////////////////////////////////////////////////////////////////////////
function selectfromdb(){
$x = array();
$con = mysql_connect("localhost","root","root");
mysql_select_db("my_db", $con);
mysql_query("set character_set_server='utf8'");
mysql_query("set names 'utf8'");
$result = mysql_query("SELECT idip FROM id");
$c = 0;
while($r = mysql_fetch_array($result))
{
$x[$c] = $r['idip'];
$c++;
}
return $x;
}
///////////////////////////////////////////////////////////////////////
$y = selectfromdb();
$i = 0;
while ($i < sizeof($y)){
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*',$y[$i]) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered</br>' . PHP_EOL;
else
echo 'Message successfully delivered</br>' . PHP_EOL;
$i++;
}
echo 'end</br>';
// Close the connection to the server
fclose($fp);
?>
but it just sent for 507 , then it says : Message not delivered
for all the rest .

The problem is that apple closes the connection after X messages that were sent to unavailable device-IDs.
Clean up your collection / database of deviceids by consuming the APNS feedback service, then finish the deployment of your APNS messages.

Related

Parse error: syntax error, unexpected token ":"

I am trying to migrate an existing API that used APNs to send and receive messages to be compatible with the new APNs Provider API.
The following script worked for sending test notifications to my testing device before Apple stopped supporting the legacy binary protocol.
//simplepush.php
<?php
// Put your device token here (without spaces):
$deviceToken = 'EXAMPLETOKEN';
// Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'Hello!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://api.sandbox.push.apple.com:443', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
Sending Notification Requests to APNs states that the :method and :path header fields are required for a connection to APNs.
I've copied the code from the link to the original test script.
<?php
HEADERS
- END_STREAM
+ END_HEADERS
:method = POST
:scheme = https
:path = /3/device/EXAMPLETOKEN
host = api.sandbox.push.apple.com
apns-id = eabeae54-14a8-11e5-b60b-1697f925ec7b
apns-push-type = alert
apns-expiration = 0
apns-priority = 10
DATA
+ END_STREAM
{ "aps" : { "alert" : "Hello" } }
// Put your device token here (without spaces):
$deviceToken = 'EXAMPLETOKEN'; // Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'Hello!';
///////////////////////////////////////////////////////////////////. /////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://api.sandbox.push.apple.com:443', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
When I try to run the script, the terminal output is:
PHP Parse error: syntax error, unexpected token ":" in /Users/Desktop/simple push folder/simplepush.php on line 6
What is the correct way to add the newly required header fields to this script?
Note: I've used the following Apple documentation to send a test notification to my testing advice.
PHP said that your file have a syntax error. I believe it has nothing to do with request header.

How to control not response error sending push to APNS from PHP

I'm having some problems with my implementation because it crash in a random way after 400 - 500 sendings.
I was wondering why the best APNS tutorials for PHP and other platforms advice you to sleep a little (o a lot!) after sending some messages to the APNS server.
Why to sleep your code when sending iOS Push Notifications?
The crash I get is
<html><head><title>500 Internal Server Error</title></head><body>
<h1>Internal Server Error</h1>
<p><i>stream_socket_client(): php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known</i></p>
<p>#0 /Users/MyUser/development/projects/project/project-api/helpers/PushNotificationHelper.php:407 stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195',0,'',60,5,NULL)<br />...
My source code:
static function pushIOS($ios_devices, $push_type, $data_array){
$log = new Logger('PushConsumer');
$log->pushHandler(new StreamHandler(BASEPATH.'log/push.log', Logger::DEBUG));
// set time limit to zero in order to avoid timeout
set_time_limit(0);
// this is the pass phrase you defined when creating the key
$passphrase = 'mypass';
// load your device ids to an array
$deviceIds = $ios_devices;
// this is where you can customize your notification
//payload = '{"aps":{"alert":"' . $message . '","sound":"default"}}';
$msg = array
(
'type' => $push_type,
'message' => $data_array,
);
$payload = json_encode($msg);
$result = 'Start' . '<br />';
////////////////////////////////////////////////////////////////////////////////
// start to create connection
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', BASEPATH.'scripts/certificates/appleck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$log->addDebug(count($deviceIds)." devices will receive notifications.'");
//echo count($deviceIds) . ' devices will receive notifications.<br />';
// Open a connection to the APNS server
$fp = stream_socket_client(F3::get('apns_url'), $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp) {
$log->addDebug("Failed to connect: $err $errstr");
exit("Failed to connect: $err $errstr" . '<br />');
} else {
$log->addDebug("Apple service is online.");
foreach ($deviceIds as $item) {
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $item) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result) {
$log->addDebug("Undelivered message to push token: $item");
//echo 'Undelivered message count: ' . $item . '<br />';
} else {
$log->addDebug("Delivered message to push token: $item");
//echo 'Delivered message count: ' . $item . '<br />';
}
}
fclose($fp);
$log->addDebug("The connection has been closed by the client");
}
$log->addDebug(count($deviceIds)." devices have received notifications");
// wait for some time
sleep(2);
}
The line with the crash:
$fp = stream_socket_client(F3::get('apns_url'), $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);

Don't send notifications to multiple iOS in PHP

I can not send push messages to multiple iOS devices querying the database, it only sends it to the last record , I tried various solutions found in stackoverflow but it still fails in any , can anyone help me?
<form action="" method="post">
<label for="txtmensagem">Mensagem:</label>
<input type="text" name="txtmensagem" size="30"/>
<input type="submit" value="Enviar"/>
</form>
<?php
//conect with database
include_once('conexao.php');
$message = stripslashes(ucfirst($_POST['txtmensagem']));
// executa a query
$dados = mysql_query("SELECT * FROM token_push WHERE so='ios'");
$passphrase = 'XXXXX'; //pushchat
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'xx.pem');//xx.pem
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// 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 conect to APNS
//if (!$fp)
//exit("Falha na conexão: $err $errstr" . PHP_EOL);
//echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
if (!empty($message)){
$body['aps'] = array(
'alert' => $message,
'sound' => 'default',
'conteudo' => $conteudo,
'comando' => 'noticia',
'badge' => +1,
'idConteudo' => mysql_insert_id(),
);
// Encode the payload as JSON
$payload = json_encode($body);
//insert token in array
while ($row = mysql_fetch_array($dados)) {
$deviceToken = array();
$deviceToken[] = $row['token'];
}
foreach($deviceToken as $device){
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $device) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
}
}
//return if send or not
if (!$result)
echo 'Ops!' . PHP_EOL;
else
echo 'Aehoooooo!' . PHP_EOL;
// Close the connection to the server
fclose($fp);

iOS push notification not working using PHP

I am trying to implement push notification in iOS in PHP using APNS library. Here is my code :
<?php
// Put your device token here (without spaces):
$deviceToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
// Put your private key's passphrase here:
$passphrase = 'XXXXXX';
// Put your alert message here:
$message = 'My first push notification!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'Certificates.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// 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)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));print_r($result);
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
?>
It show message sending successfully but in iOS it does not show notification.
2015-07-28 08:32:39 Connected to APNS result = 97
2015-07-28 08:32:39 Message successfully delivered
2015-07-28 08:32:39 Connection closed to APNS
Why this is happening? Am I missing anything ?
his mistake is with the ios 9 if so stop using the code in objective C and use in swift as it has a bug in generating objectiv token - C for ios9.
I recommend urgent change your code.
Also through this thought was the server when the scheduled ios changed for swift everything was resolved and my php was almost equal.
Care:
$ msg = chr (0). pack ('N', 32). pack (H * ','. '$deviceToken [0].'). pack ('N', strlen ($ payload)). $ payload;
There are two potential reason that is causing this:
Your app is in foreground
Your device token is invalid
In my app. I am directly getting deviceToken that's in NSData
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *deviceTokenString = [NSString stringWithFormat:#"%#", deviceToken];
// this is producing something like:
// <xxxxxxx 9b0f527f xxxxxxxx 2727ed28 xxxxxxxx 4e693a61 xxxxxxx ac2f7dbb>
//
// and i am directly saving that to my servers database
Here's what i have in my server.
$from_database = "<xxxxxxx 9b0f527f xxxxxxxx 2727ed28 xxxxxxxx 4e693a61 xxxxxxx ac2f7dbb>";
// this removes the '<' and '>' to make the device token valid
//
$token_string = substr($from_database, 1, -1);
$token_array[] = $token_string;
// you can also add multiple 'token_string' to the 'token_array' for push notification broadcasting, i am currently doing that and it is working properly.
...
public function __push_notification($message_input, $token_array)
{
$message = stripslashes($message_input);
$passphrase = 'xxxxxx';
$cert = realpath('xxx.pem');
$payload = '{
"aps" :
{
"alert" : "'.$message.'",
"badge" : 1,
"sound" : "bingbong.aiff"
}
}';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $cert);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
{
// echo "Failed to connect $err $errstr <br>";
return;
}
else
// echo "Post notification sent<br>";
$dev_array = array();
$dev_array = $token_array;
foreach ($dev_array as $device_token)
{
$msg = chr(0) .
pack("n", 32) .
pack('H*', str_replace(' ', '', $device_token)) .
pack("n", strlen($payload)) .
$payload;
// echo "sending message :" . $payload . "n";
fwrite($fp, $msg);
}
fclose($fp);
}
Also check this, might be helpful: Facing problems in ios push notification php code

ios push notification performance

This is my php push notification code for ios below:
<?php
// Put your device token here (without spaces):
$deviceToken = "********************************************";
// Put your private key's passphrase here:
$passphrase = "********";
function pushIOSNotification($message)
{
GLOBAL $deviceToken;
GLOBAL $passphrase;
$ctx = stream_context_create();
$path = dirname(__FILE__).'/ck.pem';
//echo $path;
stream_context_set_option($ctx, 'ssl', 'local_cert', $path);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// 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)
exit("Failed to connect: $err $errstr" . PHP_EOL);
//echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
}
This code is only for one device,
if I need send to everyone and support localization,
this code will be like these below.
foreach($deviceTokens as $deviceToken){
$deviceOS = "query this device os from memcache";
if($deviceOS == "ios")
{
$lang = "query this device langauge from memcache";
$message = $messageData[$lang];
pushIOSNotification($deviceToken,$message);
}
}
but I doubt this performance of this code,
because deviceTokens length is the number of all members.

Categories