stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Connection refused)

20,682

Solution 1

Try this code and make sure your certificate mentioned in server path is particularly ck.pem

    $deviceToken = 'f672c26cbfb279e45c1b66d0ddb738d8043c785d5bb8dd20a72d52ae88d4a604';
    // Put your private key's passphrase here:
    $passphrase = 'pushchat';

    // Put your alert message here:
    $message = 'Hello';

    ////////////////////////////////////////////////////////////////////////////////

    $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' => $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);

    }

Solution 2

I found this article while having the same issues and my problem was actually two issues and thought it could be useful here. I am on Ubuntu / Php 5.5

Test your certificates!

prompt\#: openssl s_client -connect gateway.sandbox.push.apple.com:2195
     -cert ./push-crt.pem 
     -key ./push-key.pem 
     -CApath ./entrust_root_certification_authority.pem

When I found the above test I realized I was missing the root authority certificate on my server, item 1. Once I ran the above and it worked I realized the library I was using only passed one file, more on that in item two.

1. Root Certificate

On my server I did not have the correct root certificate installed and therefore could not verify my PEM file. I'll get to that next. Once I found this page [Where to get the Entrust Root CA PEM file?][1] I checked and I has the same problem. I assume you d/l to your home folder...

prompt\#: sudo cp ~/entrust_root_certification_authority.pem 
    /usr/local/share/ca-certificates/entrust_root_certification_authority.crt
prompt\#: sudo update-ca-certificates

You should see a response indicated a certificate was installed or updated. Now, I was getting somewhere. I started to get a different connection error directly related to my PEM file. Something I could work with.

2. Your PEM file

If you are using a library like mine which passes one file and you passed the above test using both your cert and key then you need to combine your key and cert. For me, using my sample names above of push-crt.pem

prompt\#: cat push-crt.pem > push.pem
prompt\#: echo >> push.pem
prompt\#: cat push-key.pem >> push.pem

then I used the combined key/certificate pair and everything started to work.

Phew. Hope it helps someone.

Share:
20,682
Admin
Author by

Admin

Updated on February 08, 2020

Comments

  • Admin
    Admin about 4 years

    I made a php file for sending notification to the apple iphone users. Its working for the other server but not working in my server. I have made the .pem file accurately and also opened the port number 2195,2196. But still its not working. Please someone help me out to get rid of this issue. Here is my php code for sending push notification:

     <?php
    // Put your device token here (without spaces):
    $deviceToken = 'f672c26cbfb279e45c1b66d0ddb738d8043c785d5bb8dd20a72d52ae88d4a604';
    // Put your private key's passphrase here:
    $passphrase = 'pushchat';
    // Put your alert message here:
    $message = 'Welcome in testing';
    $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' => $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);
    ?>
    
  • andreszs
    andreszs over 6 years
    Why would you use STREAM_CLIENT_PERSISTENT if you are closing the connection at the end?