I am trying to send iOS push notifications from a PHP App Engine backend but I am receiving the following errors. I am not sure if there is a problem with the certificate, the way I'm doing it, or something specific to App Engine. This is my first time sending push notifications to iOS.
Here is my code :
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
{
//Handle Error
}
$body['aps'] = array(
'alert' => $data["message"],
'sound' => 'default',
);
$body["postID"] = $data["postID"];
$body["groupID"] = $data["groupID"];
$body["type"] = $data["type"];
$payload = json_encode($body);
foreach ($registrationIds as $registrationID)
{
$deviceToken = $registrationID;
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
$result = fwrite($fp, $msg, strlen($msg));
}
fclose($fp);
Here is the error I get :
PHP 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 fakefile.php
I have no idea what the cause is. Thanks in Advance
UPDATE :
That is no longer the error I get. Now I get this :
PHP Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error)
May be your port 2195 and 2196 are closed from server side that are blocking push notifications.
In stream_context_set_option you did not include the full path to the ck.pem file . After giving the full path there was no error.
Following is code may help to solve your problem.
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', '/Users/Development/Dev/ck.pem');
Following code for checking port is enable for Push notification.
<?php
chkServer('gateway.sandbox.push.apple.com', 2195);
//chkServer('gateway.push.apple.com',2195);
function chkServer($host, $port)
{
$hostip = #gethostbyname($host);
if ($hostip == $host) {
echo "Server is down or does not exist";
} else {
if (!$x = #fsockopen($hostip, $port, $errno, $errstr, 5)) {
echo "Port $port is closed.";
} else {
echo "Port $port is open.";
if ($x) {
#fclose($x);
}
}
}
}
?>
Happy coding.
Related
I have a code which is supposed to send IOS push messages but it is giving me an error.
My code:
$streamContextCreate = stream_context_create();
stream_context_set_option($streamContextCreate, 'ssl', 'local_cert', '/home/devmzad/public_html/public/ios/MzadDevCertificates.pem');
$fp = stream_socket_client(
'ssl://gateway.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContextCreate);
echo "<pre>";
print_r($fp); //gives error here.
die;
the error I receive is below:
stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14094438:SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error
I would appreciate if someone could help me with it. Thanks.
Please try the below code :
<?php
/* We are using the sandbox version of the APNS for development. For production
environments, change this to ssl://gateway.push.apple.com:2195 */
$apnsServer = 'ssl://gateway.sandbox.push.apple.com:2195';
/* Make sure this is set to the password that you set for your private key
when you exported it to the .pem file using openssl on your OS X */
$privateKeyPassword = '1234';
/* Put your own message here if you want to */
$message = 'Welcome to iOS 7 Push Notifications';
/* Pur your device token here */
$deviceToken =
'05924634A8EB6B84437A1E8CE02E6BE6683DEC83FB38680A7DFD6A04C6CC586E';
/* Replace this with the name of the file that you have placed by your PHP
script file, containing your private key and certificate that you generated
earlier */
$pushCertAndKeyPemFile = 'PushCertificateAndKey.pem';
$stream = stream_context_create();
stream_context_set_option($stream,
'ssl',
'passphrase',
$privateKeyPassword);
stream_context_set_option($stream,
'ssl',
'local_cert',
$pushCertAndKeyPemFile);
$connectionTimeout = 20;
$connectionType = STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT;
$connection = stream_socket_client($apnsServer,
$errorNumber,
$errorString,
$connectionTimeout,
$connectionType,
$stream);
if (!$connection){
echo "Failed to connect to the APNS server. Error no = $errorNumber<br/>";
exit;
} else {
echo "Successfully connected to the APNS. Processing...</br>";
}
$messageBody['aps'] = array('alert' => $message,
'sound' => 'default',
'badge' => 2,
);
$payload = json_encode($messageBody);
$notification = chr(0) .
pack('n', 32) .
pack('H*', $deviceToken) .
pack('n', strlen($payload)) .
$payload;
$wroteSuccessfully = fwrite($connection, $notification, strlen($notification));
if (!$wroteSuccessfully){
echo "Could not send the message<br/>";
}
else {
echo "Successfully sent the message<br/>";
}
fclose($connection);
?>
Whenever I am trying to give Push notifications it throws me multiple error,
I have researched very well yet no solution.
1.stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
-
2.Severity: Warning
Message: stream_socket_client(): Failed to enable crypto
-
3.Severity: Warning
Message: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error)
-
4.Failed to connect: 0
Below is my code:
// Sends Push notification for iOS users
public function iOS($data, $devicetoken)
{
$deviceToken = $devicetoken;
$passphrase= "";
$ctx = stream_context_create();
// ck.pem is your certificate file
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.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);
// Create the payload body
$body['aps'] = array(
'alert' => array(
'title' => $data['mtitle'],
'body' => $data['mdesc'],
),
'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));
// Close the connection to the server
fclose($fp);
if (!$result)
return 'Message not delivered' . PHP_EOL;
else
return 'Message successfully delivered' . PHP_EOL;
}
Can anyone help me to sort it out?
add following line
stream_context_set_option( $ctx , 'ssl', 'verify_peer', false);
if you have set password while generating pem file then you have to mention it in following line
$passphrase= "";
if you have not set then this error due to pem file.Its not generated properly.
I'm working on push notification in IOS with php server and I produced the certificate and keys of the app also I'm ensure from unblocking port for ssl://gateway.sandbox.push.apple.com:2196 and 2195 but at all time I get this error during try to connect on ssl also I'm sure from the permission of all key files
Warning: stream_socket_client(): SSL: crypto enabling timeout in /Users/samahahmaed/Desktop/CER/newspush.php on line 24
Warning: stream_socket_client(): Failed to enable crypto in /Users/samahahmaed/Desktop/CER/newspush.php on line 24
Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /Users/samahahmaed/Desktop/CER/newspush.php on line 24
Failed to connect: 0
Edited:
When I'm trying this command
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushCertificate.pem -key PushKey.pem -CApath /etc/ssl/certs/Entrust_Root_Certification_Authority.pem
I get this error
CONNECTED(00000003)
write:errno=54
php file:
<?php
// Put your device token here (without spaces):
$deviceToken = 'mydevicetokenhere';
// Put your private key's passphrase here:
$passphrase = '1234';
$message = $argv[1];
$url = $argv[2];
if (!$message || !$url)
exit('Example Usage: $php newspush.php \'Breaking News!\' \'https://raywenderlich.com\'' . "\n");
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apple_push_notification_production.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',
'link_url' => $url,
);
// 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 searched a lot about this issue and I tried all possible solutions but without any result what I can do now ?
Edited:
After add -debug to openssl command the most strange thing these lines:
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apple_push_notification_production.pem');
This line looks like you are using production certificate to connect to sandbox APNS. Try using development certificate. You can get the same from apple developer dashboard.
I had succeeded earlier on sending a push notification to my iPhone using raywenderlich's excellent tutorial here http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1 and running the php script using the mac terminal, however, now I am trying to achieve the same thing only now I have the push.php script uploaded to my server and run the script every 5 min via Cron Job but i get this error now:
stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Connection timed out)
Like I said before it was working fine earlier when I was running the script through the terminal. I think the problem is that the php script from the server cannot access my push certificates. How do I give the script access to them? Please help!
Heres the php script if it helps:
<?php
// Assign data into variables
$deviceToken = "e39ffc6b98f649f127d07d2d881bc9faa621a3c5d59f9647e64f6452fc37af6c";
$passphrase = "9q3n6k80";
$sound = '';
$blank = "";
$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.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' => "mic check",
'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 succesfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
Thank You!
EDIT: Im using the File Manager in Bluehost to upload files
I apologize in advance, but I am asking the same question as here: How to send iOS Push Notifications using TLS and PHP? because the problem remains unresolved. Here is the Ray Wenderlich tutorial php code I am using to try to send a push notification, as modified per SO post's recommendations:
<?php
// Put your device token here (without spaces):
$deviceToken = '325bcd9d15ab8b5f8ff6f4f3d5ab3a5254f1ce775d48828476f4aaff4c5c3d3f';
// 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', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');
// Open a connection to the APNS server
$fp = stream_socket_client(
'tls://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);
I also downloaded the entrust_2048_ca.cer file and ensured that it shows up on the System tab of my keychain access. When I run this php file, I still get the following errors, which is the same set of errors I got before making changes to reflect use of tls:
error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure in /Users/aileenann/Desktop/SimplePush/simplepush.php on line 22
Warning: stream_socket_client(): Failed to enable crypto in /Users/aileenann/Desktop/SimplePush/simplepush.php on line 22
Warning: stream_socket_client(): unable to connect to tls://gateway.sandbox.push.apple.com:2195 (Unknown error) in /Users/aileenann/Desktop/SimplePush/simplepush.php on line 22
Failed to connect: 0
What else needs to be changed? Why does the tls apple server still think I am trying to use SSL3 when I have specified tls in the URL?
Thank you for any suggestions.