Sending multiple iPhone notifications - iphone

My code works ok when I need to send one notification, but each time when I need to send more than one, it only sends the first one. Here is the code:
<?php
$device_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'apns-dev.pem';
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
$payload['aps'] = array('alert' => 'some notification', 'badge' => 0, 'sound' => 'none');
$payload = json_encode($payload);
for($i=0; $i<5; $i++)
{
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_token)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
}?>
What am I doing wrong?
Thx in advance,
Mladjo

You should open the connection to apns only once. Right now you are opening it in the loop which is wrong. I'm also using a slightly different scheme to build my messages. You should instead do it in this way:
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
for($i=0; $i<5; $i++)
{
$apns_message = chr(0).pack('n', 32).pack('H*', $device_token).pack('n', strlen($payload)).$payload;
fwrite($apns, $apnsMessage);
}?>
Also note that apple recommends using the same connection to send all your push notifications so you shouldn't connect every time you have a push notification to send.

Have a look at the following document:
http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW3
It says that multiple notifications should be sent in a single transmission using the TCP/IP Nagle algorithm. You can find out what the Nagle algorithm is here:
http://en.wikipedia.org/wiki/Nagle%27s_algorithm
so I believe the code to create the message should look like:
// Create the payload body
$body['aps'] = array(
'alert' => "My App Message",
'badge' => 1);
// Encode the payload as JSON
$payload = json_encode($body);
// Loop through the token file and create the message
$msg = "";
$token_file = fopen("mytokens.txt","r");
if ($token_file) {
while ($line = fgets($token_file)) {
if (preg_match("/,/",$line)) {
list ($deviceToken,$active) = explode (",",$line);
if (strlen($deviceToken) == 64 && intval($active) == 1) {
// Build the binary notification
$msg .= chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
}
}
}
fclose ($token_file);
}
if ($msg == "") {
echo "No phone registered for push notification";
exit;
}
And now open the TCP connection and send the Message....

Taking a shot in the dark here. Looking at your for loop.
It looks like you open the connection and push the message... but does that connection close itself? Do you need to initiate a new connection for each push thereby making it necessary to close the first connection at the end of the while loop before re-initiating another?

Related

Even if I read many page I can't receive notification on my device

I setup a server with manager-apns on it, and so fare the registering, and part of sending is working.
My app is able to register to the APNS service, but still i can't receive any notification.
And when I send I can see it queued, then delivered, but the message never reach my app.
I try to troubleshoot with the TN2265 from apple, and using the PersistentConnectionLogging debug tool I can't see any 'Received message for enabled topic' for my app.
I have no clue where to look for !
the only wierd thing I saw is the 'Sending filter message for enabled hashes' happen 2 times, one for my app only:
2013-07-26 15:08:43 +0200 apsd[76]: <APSCourier: 0x1cd7acd0>: Sending filter message for enabled hashes {
<f64ea2b9 ab3ff7b0 fd1434d0 29915479 7ede3451> = "ch.arno.airmet";
} and ignored hashes {
}
and one time with all other app that appear under notification service on my phone:
2013-07-26 14:52:21 +0200 apsd[76]: <APSCourier: 0x1cd5b970>: Sending filter message for enabled hashes {
<00d2590f de623fa5 4daaff34 141ee00e 0901f374> = "ch.admin.meteoswiss";
<5323275a 2f8a5b9f 02c764cc 626ee7e6 2f63f1e0> = "com.viber";
<852ba2ea 01feadaf c01d9008 e4126d14 ec5259b3> = "com.apple.itunesconnect.mobile";
<ed98cabb 18f6456b fddf7fec 19097b75 a21217ac> = "com.apple.itunesstored";
<b1e43d18 e02389f7 6e7468cb f2724d06 7bdfe1b2> = "org.arrl.arrl";
<bc1f77cb da300ce4 81e852d5 bf22e623 ec5e091a> = "uk.co.leeus.planefinder";
<473b1564 871c0c26 28458f58 f23fc00e c118dd9f> = "com.solarimpulse.iosApp";
<e7f612ad e3f961cb 0ac0a81b 6bdf57bc 694f7428> = "ch.mobilemed.echo112";
<0ce2a170 a161da7f 5f69bf26 ee0809fb 0668e1ce> = "com.facebook.Facebook";
<12b4fdbc cba5eaba 2c17bdbe 22dcc0ee 57835566> = "net.whatsapp.WhatsApp";
<e85619ab d42029c7 481a7ac1 9092bb46 90cbee76> = "com.apple.ess";
<7534fab8 84f14472 afe97dae be5befc4 705da00b> = "com.medlmobile.nra";
<7981dd6f f81e3c91 d91509d5 ebcd5e79 bd4af29f> = "ch.local.search.launcher";
} and ignored hashes {
<ca7bf4cd b904cd8c 41b61ff6 9518dd16 6b76780b> = "com.shazam.Shazam";
<07f67690 61ef66b3 5263ccfc 4999aebd 24660517> = "com.giggleup.tc1free";
<ecf79b66 385fd443 09d13301 97a333b0 3399c7da> = "ch.teleboy.Teleboy";
<10132f99 870d0f9d 70361cf6 6d6610a5 ed624d9f> = "ch.edipresse.lematin";
<cee727be 3abd4b5a b08f2dea 1386944f de9c0a74> = "com.ebay.iphone";
<22d7a21b 76ee7ffe 6ca350b5 99050ab6 262c78b0> = "ch.rts.couleur3.ios";
<88b112b4 1932b794 6c108a0a 216553b9 0fffaece> = "com.chairentertainment.IB2";
<9f9c9ad5 b5655e77 2381b57c 623b27f3 45edfc7b> = "com.sega.sjump";
<2a66964c 844725bd d0eef3d0 ea63cd04 9923faf0> = "ch.edipresse.vqh";
<e24289ab caeb387d 21b5083c 68b647ce 4df387e3> = "com.outfit7.talkingdog";
<40165135 742995c5 acafd4cf e8492faf 5c3f9780> = "5Q4J53EFRC.com.sbb.ch";
<c0cbf607 951fdb5b c0905310 b8524d4c 6f3a187d> = "com.touchpress.atlas.ipad.english";
<a4421ecb ef0ca44c f5f683ee 4a817b6e 225a16e5> = "com.glu.pinkslip";
<cf2c3d22 a50d9f3a f1d37d98 6afc8971 0b5c2948> = "com.vitotechnology.StarWalk";
<3a7c8c40 a9a7de34 4c3a35c8 9feaa514 72310917> = "com.zentertain.ringmakerfree";
<a2e43ec2 cad8bc3b 99a2ba8f a9626c71 62b7068a> = "com.outfit7.talkingtom";
<8c3f23ff 0dde87a3 2ad02d41 3fbd69b4 86f86983> = "com.outfit7.talkinggina";
<9def7a9f f25f2141 ef4f9008 f3b16620 f888f66e> = "com.outfit7.talkingtom2";
<fffc05c7 628714bd 08802dd7 8728875c 63c09447> = "com.linkedin.LinkedIn";
}
I also try this code to send push notification:
<?php
// Put your device token here (without spaces):
$deviceToken = 'ad53879a3ad06c5d23acd502e19f6488fb3a722ac163c5f47b3ba4d3df4bef54
';
// Put your private key's passphrase here:
$passphrase = '';
// Put your alert message here:
$message = 'My first push notification!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'include/certs/airmet/sandb
ox.pem');
stream_context_set_option($ctx, 'ssl', 'verify_peer', false );
stream_context_set_option($ctx, 'ssl', 'ciphers', 'ALL:SSLv3:TLSv1');
stream_context_set_option($ctx, 'ssl', 'cafile', 'ca.pem');
//stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'tcp://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($pay
load)) . $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);
?>

IOS push notification do not reach the device from the MDM server

I am working on mobile device management system and my push notification isnt working. My Code is
//$apnsHost = 'gateway.push.apple.com';
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'PushCert.pem';
// Put your device token here (without spaces):
$deviceToken = 'my-device-token'; //I have replaced my actual token here
// Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'My first push notification!';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $apnsCert);
//stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 60, STREAM_CLIENT_CONNECT, $ctx);
if (!$fp)
exit("Failed to connect: $error $errorString" . 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);
I got the message like "Connected to APNS Message successfully delivered." but notification doesnt came on the IPhone device. What else should I check and what can be the solution? I also checked the Iphone logs into the configuration utility but no logs are seen when I run my script.

How to send Push Notification to multiple devices?

This is the first time I am using push notification in my App. I have gone through sample applications along with books and I got how to send push notification to a single device. But I am not getting exactly what changes should I do in my program to send push notification to multiple devices. I am using 'PushMeBaby' application for server side coding.
Please, help me out.
Try this example code and modify for your environment.
$apnsHost = '<APNS host>';
$apnsPort = <port num>;
$apnsCert = '<cert>';
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
$payload['aps'] = array('alert' => 'some notification', 'badge' => 0, 'sound' => 'none');
$payload = json_encode($payload);
// Note: $device_tokens_array has list of 5 devices' tokens
for($i=0; $i<5; $i++)
{
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_tokens_array[i])) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
}?>
This article helps verifying drop connection and connection status: Apple Push Notification: Sending high volumes of messages
Other reference links:
How can I send push notification to multiple devices in one go in iPhone?
and
how to handle multiple devices when using Push Notification?
I found that you have to create a new stream_context_create for each fwrite to prevent apple from closing the connection for a bad token.
This is what I have done here
<?php
set_time_limit(0);
$root_path = "add your root path here";
require_once($root_path."webroot\cron\library\config.php");
require_once($root_path."Vendor\ApnsPHP\Autoload.php");
global $obj_basic;
// Basic settings
$timezone = new DateTimeZone('America/New_York');
$date = new DateTime();
$date->setTimezone($timezone);
$time = $date->format('H:i:s');
//Get notifications data to send push notifications
$queueQuery = " SELECT `notifications`.*, `messages`.`mes_message`, `messages`.`user_id`, `messages`.`mes_originated_from` FROM `notifications`
INNER JOIN `messages`
ON `notifications`.`message_id` = `messages`.`mes_id`
WHERE `notifications`.`created` <= NOW()";
$queueData = $obj_basic->get_query_data($queueQuery);
if(!empty($queueData)) {
// Put your private key's passphrase here:
$passphrase = 'Push';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'server_certificates_bundle_sandbox.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 '<br>'.date("Y-m-d H:i:s").' Connected to APNS' . PHP_EOL;
foreach($queueData as $val) {
// Put your device token here (without spaces):
$deviceToken = $val['device_token'];
// Create message
// Get senders name
$sql = "SELECT `name` FROM `users` WHERE id =".$val['user_id'];
$name = $obj_basic->get_query_data($sql);
$name = $name[0]['name'];
$message = $name." : ";
// Get total unread messaged for receiver
$query = "SELECT COUNT(*) as count FROM `messages` WHERE mes_parent = 0 AND user_id = ".$val['user_id']." AND mes_readstatus_doc != 0 AND mes_status = 1";
$totalUnread = $obj_basic->get_query_data($query);
$totalUnread = $totalUnread[0]['count'];
$message .= " This is a test message.";
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'badge' => $totalUnread,
'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 '<br>'.date("Y-m-d H:i:s").' Message not delivered' . PHP_EOL;
} else {
$sqlDelete = "DELETE FROM `notifications` WHERE id = ".$val['id'];
$query_delete = $obj_basic->run_query($sqlDelete,'DELETE');
echo '<br>'.date("Y-m-d H:i:s").' Message successfully delivered' . PHP_EOL;
}
}
// Close the connection to the server
fclose($fp);
echo '<br>'.date("Y-m-d H:i:s").' Connection closed to APNS' . PHP_EOL;
} else {
echo '<br>'.date("Y-m-d H:i:s").' Queue is empty!';
}

Apple push notification service - no notification on device

This problem is driving me crazy. I'm implementing APNS. I already google and followed several tutorials. I implemented the server an it seems to work find here is the code:
<?php
$deviceToken = 'XXXX';
// Passphrase for the private key (ck.pem file)
// $pass = '';
// Get the parameters from http get or from command line
$message = $_GET['message'] or $message = $argv[1] or $message = 'Message received from javacom';
$badge = (int)$_GET['badge'] or $badge = (int)$argv[2];
$sound = $_GET['sound'] or $sound = $argv[3];
// Construct the notification payload
$body = array();
$body['aps'] = array('alert' => $message);
if ($badge)
$body['aps']['badge'] = $badge;
if ($sound)
$body['aps']['sound'] = $sound;
/* End of Configurable Items */
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
// assume the private key passphase was removed.
//stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);
$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); // for production change the server to ssl://gateway.push.apple.com:219
if (!$fp) {
print "Failed to connect $err $errstr\n";
return;
} else {
print "Connection OK\n";
}
$payload = json_encode($body);
$msg = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload;
print "sending message :" . $payload . "\n";
fwrite($fp, $msg);
fclose($fp);
?>
It seems to work fine. I don't get any errors. But I don't get any push notification on my device. I don't know where the error could be. I also implemented the feedback script. No error and no output. My App is also prepared.
Thanks in advance.
Apple just released a technical note titled "Troubleshooting Push Notifications". It has tips for both sending and receiving. Maybe something there can help.

iPhone Push Notification (PHP) aren't sending

I set up a PHP script to send push notifications using this tutorial. I run the script without any errors but nothing shows up on my device. What am I doing wrong?
Create a common function for the push notification Pass the following params in the function devicetoken, message and extra params as per your app requirement.
if you are using developer pem file then you have to use "gateway.sandbox.push.apple.com:2195" and if you are using distributer panm file the you have to use "gateway.push.apple.com:2195"
public function pushtoios($devicetoken, $message, $params = array()) {
$passphrase = 'apple';
$ctx = stream_context_create();
/*Development pam file*/
//stream_context_set_option($ctx, 'ssl', 'local_cert', your path.'apns-dev.pem');
/*Distributer pam file*/
stream_context_set_option($ctx, 'ssl', 'local_cert', your path.'apns-distr.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
/*For Development pam file*/
//$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);
/*For Distributer pam file*/
$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 amarnew: $err $errstr" . PHP_EOL);
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
$body['type'] = $params['type'];
$body['params'] = $params;
$payload = json_encode($body);
$msg = chr(0) . pack('n', 32) . pack('H*', $devicetoken) . pack('n', strlen($payload)) . $payload;
$result = fwrite($fp, $msg, strlen($msg));
if (!$result) {
return false;
} else {
return true;
}
fclose($fp);
}
I have same problem but solved now by editing this line that i overlook...
$output = json_encode($payload);
to
$payload = json_encode($payload);
The first one will give strlen error but on my server the error does not generate. I got an strlen error when running on local host after failing trying on real server.
I also add an ssl passpharse for the local_cert, because my pem file has password.
Below is the final code that works... Please replace your_token_hex_string and your_passphrase with your own information.
$device = 'your_token_hex_string';
$payload['aps'] = array('alert' => 'This is the alert text', 'badge' => 1, 'sound' => 'default');
$payload = json_encode($payload);
$options = array('ssl' => array(
'local_cert' => 'apns_dev.pem',
'passphrase' => 'your_passphrase'
));
$streamContext = stream_context_create();
stream_context_set_option($streamContext, $options);
$apns = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
fclose($apns);