i am working on a project in PHP which requires me to push an alert notification on APNS server. I have used enhanced push notification format. but I am not receiving response as specified by the APNS docs. I am getting response in three digits usually 133, 132, 154, 138, etc. Which I concluded to be Status signs, eg. 133 is 1, 3, 3. but now I have also received 139. so I doubt that my interpretation of response is wrong. But I am not getting where it is wrong. And important thing is though I am receiving these responses Alert is getting pushed and I am receiving notification on my iPhone as well as on iPad.
My code is as follows:
$payload['aps'] = array('alert' => $message, 'badge' => 1, 'sound' => 'default');
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsPort = 2195; // default port
$apnsCert = 'apns-dev.pem'; // APNS crtificate.
$passPhrase = '';
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'passphrase', $passPhrase);
try{
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
if (!$apns) {
print "Failed to connect {$error} {$errorString}\n";
}
else {
// Sending the payload
$apnsMessage = chr(0) . pack('n', 1) . pack('n', $nid) . pack('n', time() + 604800) . pack('n', 32) . pack('H*', str_replace(' ', '', $alert_device_token)) . pack('n', strlen($payload)) . $payload;
echo 'APNS Message: ' . $apnsMessage;
$fwrite = fwrite($apns, $apnsMessage);
echo 'APNS response: ' . $fwrite;
And when this get executed i got the following response printed on the browser:
APNS Message: ��=ŸÂ� òc6–U:õŸŠ ¸Þ ÷ćÚ0ßqšÊzÂífÕnZ�`{"aps":{"alert":"Your EUR\/USD SELL alert price has been reached!","badge":1,"sound":"default"}}APNS response: 139
Can anyone please tell me what does this 139 means here. am doing anything wrong here.
The echoed "139" is the return value of fwrite(). It's the number of bytes written by fwrite()
See: PHP: fwrite
Related
I am using PHP to try to send a push notification to my iOS app. My push code looks like this:
<?php
$title="Notification";
$message=array();
$message['text']="Message";
$message['id']=1;
$to='695D55573361DB9948D09AB43EA1548A9AAECB4D23F7D836BD7F88FA94ABBE5E';
echo $to.PHP_EOL;
sendPushAPN($to,$title,$message);
function sendPushAPN($to,$title,$message)
{
$to=str_replace(" ","",$to);
// Put your device token here (without spaces):
$deviceToken=$to;
// Put your private key's passphrase here:
$passphrase = 'abc';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'aps.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
// codi existent //$body['aps'] = array('alert' => "ole.. alex",'sound'=> 'default','push_type' => 'alert');
$body['aps']=array('alert' => array('title' => 'Notificacion','body' => 'Ok Alex'),'sound' => 'default');
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// $msg = pack("C", 1) . pack("N","alert") . pack("N",$deviceToken) . pack("N", $apple_expiry) . pack("n", 32) . pack('H*', str_replace(' ', '', $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);
echo 'Result:' . $result . PHP_EOL;
}
?>
But my output always looks the same:
Connected to APNS
Result:114
and the push notification never arrives. What does 114 code mean? Is there any way to get more information about what is going on? Or perhaps I'm just using a wrong way of sending push notifications?
Your code is using the legacy binary API for APNS.
This is no longer supported.
You need to use the HTTP/2 API.
A quick web search seems to indicate that there are a few different PHP libraries that can provide this as well as sample code.
I am trying to send a push notification to IOS using php and Yii framework. I created a function as follows to get data and send notification. $data is an array which contains a message and an array inside to keep registration IDs (device tokens). I ran it on my localhost but notification is not sent to my device. By the way, the output of my function is an integer value and I cannot recognize if the message has been sent or what!?
Is there anything wrong in my code?
private function _pushIOS($data)
{
// Create a connection
$apnsHost = $this->_notificationUrl;
$apnsPort = 2195;
$apnsCert = Yii::app()->controller->createUrl('/').'/my_certificate_dev.pem';
$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);
if (!$apns)
exit("Failed to connect: $error $errorString" . PHP_EOL);
foreach($data['registration_ids'] as $deviceToken) {
$body = array();
$body['aps'] = array(
'alert' => $data['data']['message'],
'badge' => 1,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($apns, $apnsMessage, strlen($apnsMessage));
}
// Close the socket and connection to the server
#socket_close($apns);
fclose($apns);
return json_decode($result);
}
Finally, I got the answer. The problem was with the pem file path. Absolute path must be passed to the function to work. The following line should be replaced:
$apnsCert = Yii::app()->controller->createUrl('/').'/my_certificate_dev.pem';
Correct path:
$apnsCert = dirname(Yii::app()->request->scriptFile).'/my_certificate_dev.pem';
I am following a tutorial https://blog.serverdensity.com/how-to-build-an-apple-push-notification-provider-server-tutorial/ to implement connectivity with apple APNS server. The tutorial provided a php code for this:
// Open the connection
$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, 2, STREAM_CLIENT_CONNECT, $streamContext);
// Send the payload
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
// Close Resources
socket_close($apns);
fclose($apns);
I want to write this in Perl. What is the best equivalent of PHP's stream_context_create(). I tried something like the below, but didnt work.
use IO::Socket::SSL;
my $client = IO::Socket::SSL->new(
# where to connect
PeerHost => "gateway.sandbox.push.apple.com",
PeerPort => "2195",
SSL_cert_file =>'localcert.pem',
) or die "failed connect or ssl handshake: $!,$SSL_ERROR";
I successfully manage to implement an iPhone push notification server (PHP) last year; I had to change the server, and was thinking that moving files was sufficient... I was wrong, since the modification notifications are not sent anymore. There's no error, everything seems ok, but notification aren't received.
Below is my server code; anyone can think of a cause, or a way to find the problem ? (notes: the $deviceTokens var is correct, contains the device tokens, and I've successfully tested my .pem certificate with an openssl command).
$payload['aps'] = array('alert' => 'notification!!', 'sound' => 'push.aif');
$payload = json_encode($payload);
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', 'libraries/ck_prod.pem');
$apns = stream_socket_client('ssl://gateway.sandbox.push.apple.com:' . 2195, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
if($error) {
log_message('error', $errorString);
return;
}
log_message('debug', 'sending push notification...');
if($apns) {
foreach($deviceTokens as $deviceToken) {
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
}
fclose($apns);
} else {
log_message('error', 'error while sending push notification');
}
Well well... Maybe I should have notice that I was contacting the test server (gateway.sandbox.push.apple.com)... Some days are just difficult...
When I try to send Push Notifications I get this error: "Connection refused", but I don't know why... I've uploaded my apns-dev.pem in the same directory as well in the root-directory but that won't work either.
<?php
$payload['aps'] = array('alert' => 'This is the alert text', 'badge' => 1, 'sound' => 'default');
$payload = json_encode($payload);
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'apns-dev.pem';
$apnsPass = 'secret';
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'passphrase', $apnsPass);
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext);
if (!$apns) {
echo "Error: $errorString ($error)";
}
// Do this for each
$deviceToken = '00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000';
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
// End do
socket_close($apns);
fclose($apns);
?>
Does anyone know what I'm doing wrong? When I remove the passphrase and don't send it it doesn't work either...
Make sure the outgoing port 2195 is open.This would be in your firewall config.
You don't want a passphrase unless your .pem file requires one. The connection requires peer verification (option verify_peer) turned on. Also, make sure $apnsCert is the valid path to the certificate, you can use an absolute path as a sanity check.
Lastly, this shouldn't effect your ability to connect, but your device token needs to be valid.
I've know fixed that error by adding this: STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT
Know I'm not getting any errors, but I don't receive any notification. I think the Dev-token is not valid know, so, this is how it look like
numbers numbers numbers numbers numbers numbers numbers numbers.
The spaces are removed in this line:
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
Edit: I founded the problem:
My server is refusing the outgoing port, just sent a mail, hoping they can activate it...