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 .
Related
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;
I have written a function to send push notifications to iOS devices. It sends pushes to more than 100 devices for now. However sometimes it is not sending push notifications. When I debug through the process I identified based on push notification the whole process fails. but the issues is all push tokens are in valid format. So my initial code was like this.
$certificatePath = CERTIFICATE_PATH . "/".APN_CERTIFICATE_FILE;
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $certificatePath);
stream_context_set_option($streamContext, 'ssl', 'passphrase', APN_PASSWORD);
$apns = stream_socket_client(APN_HOST . ':' . APN_PORT , $error, $errorString, 2, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContext);
if (!$apns) {
echo "Failed to connect $err $errstrn";
return false;
}
$payload = array();
$payload['aps'] = array('alert' =>$message,'title'=>$title, 'sound' => 'default','data'=>array());
$payload = json_encode($payload);
foreach ($pushTokens as $pushToken)
{
$pushToken = str_replace(' ', '', $pushToken);
if(!ctype_xdigit($pushToken))
continue;
$apnsMessage = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $pushToken)) . pack ("n",strlen($payload)) . $payload;
$rst = fwrite($apns, $apnsMessage);
}
fclose($apns);
As a fix I changed the code to different way. I know this code is expensive since it open and close connection for every push notification.
$certificatePath = CERTIFICATE_PATH . "/".APN_CERTIFICATE_FILE;
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $certificatePath);
stream_context_set_option($streamContext, 'ssl', 'passphrase', APN_PASSWORD);
$payload = array();
$payload['aps'] = array('alert' =>$message,'title'=>$title, 'sound' => 'default','data'=>array());
$payload = json_encode($payload);
foreach ($pushTokens as $pushToken)
{
$apns = stream_socket_client(APN_HOST . ':' . APN_PORT , $error, $errorString, 2, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContext);
if (!$apns) {
echo "Failed to connect $err $errstrn";
return false;
}
$pushToken = str_replace(' ', '', $pushToken);
if(!ctype_xdigit($pushToken))
continue;
$apnsMessage = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $pushToken)) . pack ("n",strlen($payload)) . $payload;
$rst = fwrite($apns, $apnsMessage);
fclose($apns);
}
I am wondering if it is an issue with fwrite or somewhere else. Appreciate if someone can help me with my first method as it is speed, and run with minimum resources.
<?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
Push notification badge count not increasing.It shows always 1.I have used php to send the push from server and here is the code following:
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsCert = 'project_dev.pem';
$apnsPort = 2195;
$badgecount=1;
$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);
}else{
$messageHeader = (strlen($message) > 26) ? substr($message,0,26).'...' : $message;
$msgd=explode(':',$message);
$payload['aps'] = array('alert' => $messageHeader,'badge' => $badgecount, 'sound' => 'default','mess'=>$fromUserId.'||'.$userNamee.'||'.$userimage.'||'.$message,'type'=>'reply', 'unread_count'=>$unread_count);
$output = json_encode($payload);
$token = pack('H*', str_replace(' ', '', $token));
$apnsMessage = chr(0) . chr(0) . chr(32) . $token . chr(0) . chr(strlen($output)) . $output;
fwrite($apns, $apnsMessage);
fclose($apns);
}
badgecount always send by server side.it seems you are sending $badgecount=1; always.Update it with other value then check.It definitely reflect on IOS.
In your code you have send your badge always one that's why you getting only $badgecount 1 badge into application side.
you need to use following type to send notification badge.
$query = "SELECT badgecount FROM pushnotifications WHERE device_token = '{$device_token}'";
$query = $this->db->query($query);
$row = $query->row_array();
$updatequery = "update pushnotifications set badgecount=badgecount+1 WHERE device_token ='{$device_token}'";
$updatequery = $this->db->query($updatequery);
$device = $device_token;
$payload['aps'] = array('alert' => $pushmessage, 'badge' =>$row["badgecount"]+1, 'sound' => 'default');
$payload = json_encode($payload);
I think you now more clearify with above code.
I am able to connected to the apns and by inserting the values to database for just check i am getting "message delivered" message but it's not showing any notification....can anybody tell me where i am mistaken...
$deviceToken = '**********************';
$payload['aps'] = array('alert' => 'This is the alert text', 'badge'
=> 1, 'sound' => 'default'); $payload = json_encode($payload);
$passphrase = '***';
$apnsHost = 'gateway.sandbox.push.apple.com'; $apnsPort = 2195; $apnsCert = 'ck.pem';
$streamContext = stream_context_create(); 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)
{
$check = $errorString; $query = "INSERT INTO tbl_checkData(friend_nickname) VALUES('$check') "; $result=mysql_query($query); } else{
$check = "connected"; $query = "INSERT INTO tbl_checkData(friend_nickname) VALUES('$check') "; $result=mysql_query($query); }
$apnsMessage = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload;
//chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
$result=fwrite($apns, $apnsMessage);
if (!$result)
{
$check = 'Message not delivered' ; $query = "INSERT INTO tbl_checkData(friend_nickname) VALUES('$check') "; $result=mysql_query($query);
} else { $check = 'Message delivered' ; $query = "INSERT INTO tbl_checkData(friend_nickname) VALUES('$check') "; $result=mysql_query($query);
}
enter code here
fclose($apns);
$apnsHost = 'gateway.sandbox.push.apple.com';
remove sandbox from this url and it will run...
i have tested it...
Make sure that :
1-your app is not running because push notification used only to notify the use when the app is closed.
2-Device token of the device is correct Also make sure that the push notification certificate is also configured for the same device.
3-Make sure that you device is connected to the internet .
You can take a look at this link.
Push Notification