Pushnotification for ios via PHP Server - php

I like to implement in my IOS application. I have already created certificate for push notification and pushkey.pem when I have implement it from my mac I have received push notification in the device but when i try to implement it from my server I am getting the following error I don't know how to over come this issue please suggest me some idea to solve this issue
Errors
1)Warning: stream_socket_client() [function.stream-socket-client]: unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Connection refused)
2)Warning: fwrite(): supplied argument is not a valid stream resource
3)Warning: fclose(): supplied argument is not a valid stream resource

Hi friend please refer the tutorial
http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1
They explained all about push notification and how to implement.
You also get the iOS and PHP sample code.

see php-apn extension to PHP
Apn is a PHP extension to introduce simple yet powerful interface for
sending push notifications to iOS and OS X devices from within your
PHP code
http://pecl.php.net/package/apn

PHP CODE.. FOR IOS PUSH NOTIFICATION
to send push notification call this function and pass device id and message you send in pushnotificaion...
function pushnotification_ios($device_token, $message){
$passphrase = "Your_PEM_File_Password_Here";
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', YOUR_PEM_FILE_PATH_HERE);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// use this when you in sandbox mode..
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
// use this when you in development mode..
// $fp = stream_socket_client(
// 'ssl://gateway.push.apple.com:2195', $err,
//$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
$body['aps'] = array(
'badge' => $badge,
'alert' => $message,
'sound' => 'default',
'content-available' => '1'
);
//echo "<pre>"; print_r($body);
$payload = json_encode($body);
$msg = chr(0) . pack('n', 32) . pack('H*', $device_token) . pack('n', strlen($payload)) . $payload;
$result = fwrite($fp, $msg, strlen($msg)); //echo "<pre>"; print_R($result);
/*
if (!$result){
$data = array(
'Message' => 'Message not delivered' . PHP_EOL
);
} else {
$data = array(
'Message' => 'Message successfully delivered' . PHP_EOL
);
} //echo "<pre>"; print_R($result); */
fclose($fp);
return $result;
}

Related

iOS push using Zend Framework not working

I have implemented Push notification feature in my iOS Application. Push notification message will be pushed from the backend side.
I am using Zend framework on backend side.
Now If I do online tests with push notification it works. So its sure that .pem file created correctly & on iOS side it received push messages correctly.
But while sending push message from backend from zend framework its not working. Its showing the error message like this :
Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure in /home/virtual/site71/fst/var/www/html/application/configs/functions.php on line 316
Warning: stream_socket_client(): Failed to enable crypto in /home/virtual/site71/fst/var/www/html/application/configs/functions.php on line 316
Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /home/virtual/site71/fst/var/www/html/application/configs/functions.php on line 316
Here is implementation :
function sendIOS($deviceToken){
$passphrase = '12345678';
// Put your alert message here:
$message = 'New stock has been added by Dividend Stock!';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'pushcert_new.pem');
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)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => array(
'body' => $message,
'action-loc-key' => 'dinero App',
),
'badge' => 1
);
// 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;
fclose($fp);
}
Any guidance or hint will be highly appreciated.

Apple Push notifications working sometimes but not always

I am using php in the backend to send apple push notification.
Sometimes i am receiving the notifications sometimes i am not.
i know this is a simple code to use, if there any other ways to send the notifications. cant understand why its not delivering always and sometimes it does.
ps: this is i am using for production build
function sendPush($user_id,$message,$video_id,$not_type,$deviceToken)
{
$passphrase = 'xxxxx';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'xxx.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
$body['aps'] = array(
'alert' => $message,
'badge' => '1',
'sound' => 'default');
$body['payload'] = array(
'type' => $not_type,
'user_id' => $user_id,
'video_id' => $video_id
);
$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)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
fclose($fp);
}
Apple:
Keep your connections with APNs open across multiple
notifications; don’t repeatedly open and close connections. APNs
treats rapid connection and disconnection as a denial-of-service
attack. You should leave a connection open unless you know it will be
idle for an extended period of time—for example, if you only send
notifications to your users once a day it is ok to use a new
connection each day.
check this link Troubleshooting Push notifications from apple documentation.
There are several issues involved in not getting push notification. Based on your scenario test your code.

Ios push-notification PHP script not working for Ubuntu 14.04

I'm working on an iOS app that use iOS Push Notifications. I want to send the notification from a php script on my windows PC. I use this php script to send notification and it works well too:
// Put your device token here (without spaces):
$deviceToken = 'sdsdsdsdsczc2';
$sound = '';
// Put your private key's passphrase here:
$passphrase = 'awertf';
// Put your alert message here:
$message = 'My first push notification!';
////////////////////////////////////////////////////////////////////////////////
$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' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'badge' => +1,
'alert' => $message,
'sound' => $sound
);
// 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 php script works well on windows but now i'm working on Ubuntu 14.04 operating system and same php script is giving me error.
Message: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
I guess it's something related with port 2195. But how to solve this!
This was an enormously helpful link to find:
http://php.net/manual/en/migration56.openssl.php
http://php.net/manual/en/context.php
An official document describing the changes made to openssl in PHP 5.6
It's usefull to learn one more parameter that Tou should have set to false/true: for example "verify_peer_name"=>false
So some code looks like this:
<?php
$arrContextOptions=array(
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
);
$response = file_get_contents('ssl://'.$host.':'.$port, false, stream_context_create($arrContextOptions));
echo $response; ?>

Is it possible to send iOS push notifications to two different apps?

Im in a situation where i have one server that needs to send push notification to two different client apps without knowing which app is it.
I have two different iOS apps (2 different bundle identifiers) and i have 2 different sets of all the necessary certifications, one for each app.
I have a PHP code that receives the deviceToken and a the message to be pushed.
the code is based on reywenderlich's SimplePush that can be found here: http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1
The only part that need to change is the ck.pem file that will be different for each app.
One solution i can think of would be to try the two different ck.pem files, if one fails try the other one.
Can any one help me with implementing that in this PHP code ? or if there are any better solution suggestions ?
<?php
// Put your device token here (without spaces):
//$deviceToken = 'a6a543b5b19ef7b997b2328';
$deviceToken = $_GET["device_token"];
$message = $_GET["message"];
$elementID = $_GET["element_ID"];
// Put your private key's passphrase here:
$passphrase = '123456';
// Put your alert message here:
//$message = 'My first push notification! yay';
////////////////////////////////////////////////////////////////////////////////
$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' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);
// Create the extra data
$body['extra'] = array(
'element_id' => $elementID
);
// 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);
UPDATE:
the solution is to add another piece of code at the end, to send the same payload to the second server:
//connecting to second server
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'SecondCk.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 to note server: $err $errstr" . PHP_EOL);
// connected to server sending note msg
$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 don't know how to do this in PHP, but you should simply create the payload body + binary notification before opening the first connection and then create 2 connections(or loop a connection, if possible) to Apple's Push Server and send the same binary notification to both of them.
Best regards,
Gabriel Tomitsuka

ios push notification for multiple devices

I have the following php code for ios push notification.Here i code for 2 devices using loop in fwrite() section . the current code is working properly . My doubt is , can i pass the array of device tokens directly without using the for loop?.
<?php
// Put your device token here (without spaces):
$deviceToken[0] = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$deviceToken[1] = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy';
// Put your private key's passphrase here:
$passphrase = '123456';
// Put your alert message here:
$message = 'multiple device push notification...!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'abc.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',
'badge' => '+1'
);
// Encode the payload as JSON
$payload = json_encode($body);
for($i=0;$i<2;$i++)
{
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken[$i]) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
echo "msg may be delivered";
}
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
Its design by default, yet there is no option for passing array of device tokens. You have to iterate through the loop.
Alternate to this approach will be using third party like amazon SNS service. Here you can publish to topic(one request) and all devices that are subscribed to this topic will receive the notification.

Categories