Getting error response when sending ios apn notification from php - php

<?php
$message = 'Hello';
$badge = 3;
$sound = 'default';
$development = false;
$payload = array();
$payload['aps'] = array('alert' => $message, 'badge' => intval($badge), 'sound' => $sound);
$payload = json_encode($payload);
$apns_url = NULL;
$apns_cert = NULL;
$apns_port = 2195;
if($development)
{
$apns_url = 'gateway.sandbox.push.apple.com';
$apns_cert = 'pushcert.pem';
}
else
{
$apns_url = 'gateway.push.apple.com';
$apns_cert = 'pushcert.pem';
}
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', $apns_cert);
$apns = stream_socket_client('ssl://' . $apns_url . ':' . $apns_port, $error, $error_string, 2, STREAM_CLIENT_CONNECT, $stream_context);
echo $error;
echo $error_string;
// You will need to put your device tokens into the $device_tokens array yourself
$device_tokens = array();
foreach($device_tokens as $device_token)
{
$apns_message = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_token)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apns_message);
}
#socket_close($apns);
#fclose($apns);
?
Errors:
Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /opt/lampp/htdocs/conductexam/admin/includes/PushTest/iospush1.php on line 29
Warning: stream_socket_client(): Failed to enable crypto in /opt/lampp/htdocs/conductexam/admin/includes/PushTest/iospush1.php on line 29
Warning: stream_socket_client(): unable to connect to ssl://gateway.push.apple.com:2195 (Unknown error) in /opt/lampp/htdocs/conductexam/admin/includes/PushTest/iospush1.php on line 29
0

Related

Can't push notification to APNS to update my pass in Apple Wallet

I'm trying to push notification to APNS to update my pass in Apple Wallet app. According to this document, we only need to send the pass type identifier and the push token to APNs. Then they will take care of the rest.
$apnsHost = 'gateway.push.apple.com';
$apnsPort = 2195;
$apnsCert = base_path('app/config/passbook/certificates.pem');
$payload = ['aps' => []];
$payload = json_encode($payload);
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'passphrase', 'xxxxxx');
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if(!$apns) {
Logger::logError(1, "Passbook push notification error", ['serial_number' => $serialNumber, 'pass_type_id' => $passIdentify]);
return "Failed to connect (stream_socket_client): $error $errorString";
} else {
foreach($push_tokens as $idx => $push_token) {
$msg = chr(0) . pack('n', 32) . pack('H*', $push_token) . pack('n', strlen($payload)) . $payload;
fwrite($apns, $msg);
}
}
#socket_close($apns);
fclose($apns);
There is no error returned but it seem doesn't work. What do I do wrong? Please help.
This is the code working on my project
$errors = [];
$apnsHost = 'gateway.push.apple.com';
$apnsPort = 2195;
$apnsCert = base_path('app/config/passbook/certificates.pem');
$payload = ['aps' => []];
$payload = json_encode($payload);
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'passphrase', 'xxxxxxxxx');
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
stream_set_blocking ($apns, 0);
if( ! $apns) {
return "Failed to connect (stream_socket_client): $error $errorString";
} else {
foreach($push_tokens as $idx => $push_token) {
$msg = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $push_token)) . chr(0) . chr(mb_strlen($payload)) . $payload;
$success = fwrite($apns, $msg);
if ($success === strlen($msg)) { // log success
Logger::logPassbook('Push success', ['push_token' => $push_token]);
} else {
Logger::logPassbook('Push failed', ['push_token' => $push_token]);
}
}
}
#socket_close($apns);
fclose($apns);
return $errors;

APNS connection from php return connection timeout

This is the code that I am using for notification from PHP to iOS
#--------------- initializations ------------------------------
$message = substr($message, 0, 255);
$sound = 'default';
$development = true;
$badge = '1';
$payload['aps'] = array(
'alert' => $message,
'badge' => intval($badge),
'sound' => $sound
);
$payload = json_encode($payload);
$apns_url = NULL;
$apns_cert = NULL;
$apns_port = 2195;
#-------------------------(/initializations)---------------
// developement or live server certificate
if($development)
{
$apns_url = 'gateway.sandbox.push.apple.com';
$apns_cert = __DIR__.'/app_dev.pem';
}
else
{
$apns_url = 'gateway.push.apple.com';
$apns_cert = __DIR__.'/app_prod.pem';
}
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', $apns_cert);
$apns = stream_socket_client('ssl://' . $apns_url . ':' . $apns_port, $error, $error_string, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_CONNECT, $stream_context);
$device_tokens = $receivers;
foreach($device_tokens as $device_token)
{
$apns_message = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_token)) . chr(0) . chr(strlen($payload)) . $payload;
$result = fwrite($apns, $apns_message,strlen($apns_message));
}
#socket_close($apns);
fclose($apns);
The error I am getting is
Warning: stream_socket_client(): unable to connect to
ssl://gateway.sandbox.push.apple.com:2195 (Connection timed out)
Can anybody see what is wrong with code ?I have read many posts related to this but nothing is helping me .

Where to correctly place and name .pem file for apple notification in php

My cron files are under cron folder which is situated at the root directory. But it is always showing an error as -
Warning: stream_socket_client(): SSL: crypto enabling timeout in /home/myname/beta.myhost.com/cron/dailycron.php on line 43
Warning: stream_socket_client(): Failed to enable crypto in /home/myname/beta.myhost.com/cron/dailycron.php on line 43
Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /home/myname/beta.myhost.com/cron/dailycron.php on line 43
Line 43 is around -
$apns = stream_socket_client('ssl://' . $apns_url . ':' . $apns_port, $error, $error_string, 2, STREAM_CLIENT_CONNECT, $stream_context);
My code is as follows -
<?php
//############################# Database connection ################################/
//######################### Daily notification code ############################################/
$result = mysql_query("SELECT DISTINCT EntryId, twittes, groupname, created_at FROM users_twitte NATURAL JOIN (SELECT EntryId, MAX( created_at ) created_at FROM users_twitte GROUP BY EntryId) t");
while( $row = mysql_fetch_array($result) ) {
// Get user array from EntryId
$rowdata = $row['EntryId'];
$result2 = mysql_query("SELECT * FROM `users_subscription` WHERE EntryId = $rowdata");
while( $row2 = mysql_fetch_assoc($result2) ) {
$group_name = $row['groupname'];
$grp_usr_id = $row2['uid'];
send_notification($group_name, $grp_usr_id);
}
}
// Send Notification
function send_notification($groupname, $uid) {
// GET device token from uid
//$device_token = get_device_token($uid);
$payload = array();
$payload['aps'] = array('alert' => "THERE IS AN MESSAGE FROM $groupname", 'badge' => 0, 'sound' => 'default');
$payload = json_encode($payload);
$apns_url = NULL;
$apns_cert = NULL;
$apns_port = 2195;
$apns_url = 'gateway.sandbox.push.apple.com';
$apns_cert = '/home/myname/beta.myhost.com/cron/ck.pem';
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', $apns_cert);
stream_context_set_option($stream_context, 'ssl', 'passphrase', "12345");
$apns = stream_socket_client('ssl://' . $apns_url . ':' . $apns_port, $error, $error_string, 2, STREAM_CLIENT_CONNECT, $stream_context);
$get_token_info = get_device_token_and_type($uid);
if( 1 === $get_token_info['status'] ) {
if(0 === $get_token_info['device_type']) {
$device_token = $get_token_info['$device_token'];
$apns_message = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_token)) . chr(0) . chr(strlen($payload)) . $payload;
}
fwrite($apns, $apns_message);
#socket_close($apns);
#fclose($apns);
}
}
// GET device token for uid
function get_device_token_and_type($uid) {
$dev_tok_type_arr = array();
// GET EMAIL id from uid
$result = mysql_query("SELECT LoginData.device_token, LoginData.device_type FROM LoginData INNER JOIN users ON LoginData.userid = users.email WHERE users.uid =$uid");
if( mysql_num_rows($result) > 0 ) {
while( $rows = mysql_fetch_assoc($result) ) {
$dev_tok_type_arr = array('device_token'=> $rows['device_token'], 'device_type'=> $rows['device_type'], 'status'=> 1);
}
}
else {
$dev_tok_type_arr = array('status'=>0, 'message'=> 'No device token exists for the userid');
}
return $dev_tok_type_arr;
}
?>
My .pem file is in same cron folder and I mentioned absolute path at - $apns_cert . Let me know what I am doing wrong, I checked passphrase which is correct.
Just put your pem file in the same folder of your php script and change your variable as:
$apns_cert = 'ck.pem';

p12 to pem file using php

I checked this url
and followed the steps to generated pem file from p12 file. Below is the code to generate the pem file.
....
if ($this->file->save($uploadDirectory . $filename . '.' . $ext)) {
$filenamewithpath = $uploadDirectory . $filename . '.' . $ext;
$handle = fopen($filenamewithpath, 'r');
$p12buf = fread($handle, filesize($filenamewithpath));
fclose($file);
$password = #$p12pwd;
$results = array();
$worked = openssl_pkcs12_read($p12buf, $results, $password);
//d($results); exit;
if ($worked) {
//echo '<pre>', print_r($results, true), '</pre>';
$new_password = null;
$result = null;
$worked = openssl_pkey_export($results['pkey'], $result, $new_password);
if($worked) {
//echo "<pre>It worked! Your new pkey is:\n", $result, '</pre>';
file_put_contents( $uploadDirectory . $filename . '.pem',$result);
return array(
'success' => true,
'filename'=>$filename . '.pem',
'uploaddir' =>$uploadDirectory,
);
} else {
return array('error' => openssl_error_string());
}
} else {
return array('error' => openssl_error_string());
}
}
....
I got it working fine and generated pem file is stored in given directory. Now i am trying to use this pem file for push notification. Check the below code,
<?php
$apnsHost = 'gateway.sandbox.push.apple.com';
//$apnsHost = 'gateway.push.apple.com';
$apnsCert = 'test.pem';
$apnsPort = 2195;
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
$payload['aps'] = array('alert' => 'this is test!', 'badge' => 1, 'sound' => 'default');
$output = json_encode($payload);
$token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$token = pack('H*', str_replace(' ', '', $token));
$apnsMessage = chr(0) . chr(0) . chr(32) . $token . chr(0) . chr(strlen($output)) . $output;
//var_dump($apnsMessage); exit;
fwrite($apns, $apnsMessage);
#socket_close($apns);
fclose($apns);
?>
When i ran this code, i got below error,
Warning: stream_socket_client(): Unable to set local cert chain file `test.pem'; Check that your cafile/capath settings include details of your certificate and its issuer in /var/www/html/myserver/apns/test.php on line 13
Warning: stream_socket_client(): failed to create an SSL handle in /var/www/html/myserver/apns/test.php on line 13
Warning: stream_socket_client(): Failed to enable crypto in /var/www/html/ela/apns/test.php on line 13
Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /var/www/html/myserver/apns/test.php on line 13
Warning: fwrite() expects parameter 1 to be resource, boolean given in /var/www/html/myserver/apns/test.php on line 20
Warning: fclose() expects parameter 1 to be resource, boolean given in /var/www/html/myserver/apns/test.php on line 23
Kindly advice to fix this issue.
I would have called
'openssl pkcs12 -in cert.p12 -inpass pass:password ...something.. ..something...'
on the command line and tried to pick up or pipe its output back. Perhaps there is a wrapper for that in php, otherwise a system command seems the most easy route.
I had the same kind of issue when developing for iOS. We howerve got *.cer certificates and changed them to *.pem using the following command line:
openssl x509 -inform der -in aps_production_identity.cer -out aps_production_identity.pem
If this does not work make sure to include the private key as indicated here:
Apple Push Notification Service

How to increase stream_set_timeout() in php

I am sending push message to iPhone devices Through steam_socket using php.It's working fine but i want to send a 1000 records at time in that case i get only 50 messages then i get Warning: stream_set_timeout():
how could i increase stream socket time is there any way to handle this type problem can any one please guide me.
here is my code
for($i=0;$i<100;$i++)
{
$gstr="3f3dad52b4fb50001cb223253a3d995542209d354eXXXXXXXXXXXXXXXX";
pushMessage($gstr,$_REQUEST['msg'].$i,"Thinkingofyou");
}
function pushMessage($deviceToken,$message,$app) {
echo "Sending iPhone Push Notifications to " . $deviceToken . "<br /><br />";
echo "Your Message: " . $message . "<br />";
$time = time();
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'aps-toyPush.pem';
$streamContext = stream_context_create();
stream_set_timeout($streamContext, 3600);
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
//stream_context_set_option($streamContext, 'ssl', 'passphrase', $passphrase);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if($apns) {
$payload = array();
$payload['aps'] = array('alert' => $message, 'badge' => 1, 'sound' => 'default');
$payload = json_encode($payload);
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
} else {
echo "Connection Failed - iPhone Push Notifications Server";
echo $errorString."<br />";
echo $error."<br />";
}
// socket_close($apns);
fclose($apns);
}
Thanks for advance.
Taken from a user's post in the PHP manual:
<?php
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec'=>$sec, 'usec'=>$usec));
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec'=>$sec, 'usec'=>$usec));
?>

Categories