Push notifications (iPhone) give "111 Connection refused" - php

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...

Related

PHP stream_context_create() equivalent in perl

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";

Python equivalent to php's stream_context_create

I am following a tutorial that requires me to open a socket and send a payload with a certificate: http://blog.serverdensity.com/how-to-build-an-apple-push-notification-provider-server-tutorial/.
I am having a bit of difficulty in figuring out how to do the following with python:
// 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've used python-requests in the past. But only for simple get requests.
Can I use python-requests to rewrite the above code in python, or is there something better suited for this task?
Looking at the PHP documentation fo stream_context_create, and the tutorial you're following I think what you're trying to accomplish is opening a SSL secured socket connection to gatway.sandbox.push.apple.com.
I think the python module you want to look at is the ssl module. There's an example of connecting to a server from a client, probably setting the keyfile and certfile options of ssl.wrap_socket() to the certificate you created and registered to talk to the apple server.

Iphone push notification service problem

I am using Push Notification in my app and a PHP server that manages database with tokens and sending payload to Apple servers. Sending messages to a small number of devices (I have tried with 2) works well but when I want to send a message to entire database ( over 20.000 devices ) it doesn't work. Connection with Apple server is made ( i get no errors of connection ) but the two devices I have ( that are also in database ) do not received the message.
The PHP code is:
$apnsHost = 'gateway.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'path/to/my/certificate.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);
while($row = mysql_fetch_array($result))
{
$deviceToken=$row['token'];
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
if ($error==0)
{
echo "Notification was sent successfully to ".$row['token']."<br/>";
}
else
{
echo "Notification failure to ".$row['token']."<br/>";
}
}
socket_close($apns);
fclose($apns);
As a result I am getting "Notification was sent successfully" for all the records in database but it seems like it doesn't send the message because I don't see it on my devices. When I am using the same code to send message to 2 tokens it works well. What could be the problem? Is there an upper limit for number of devices I can send to with one connection?
Not sure if there is a limit, but I'm sure it won't be low as I have successfully sent notifications to thousands of devices at a time in the past (although currently I'm shooting them about 250-500 at a time).
Try replacing this:
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
With this:
$apnsMessage = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n", strlen($payload)) . $payload;
Also, you might be interested in trying this out: http://code.google.com/p/apns-php/

Enhanced Apple Push Notification: Response error at provider server

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

iPhone push notification server : something to do after server changed?

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...

Categories