Record the pit encountered when integrating ios push for the first time

test environment

OSX

certificate generation

There are many tutorials in this part, there are basically no pits, just skip it

try to connect

function send(){
    	$deviceToken = 'xx=';
        $ctx = stream_context_create();
        // ck.pem is your certificate file
        stream_context_set_option($ctx, 'ssl', 'local_cert', '/cert/push.pem');
        stream_context_set_option($ctx, 'ssl', 'passphrase', self::$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;
    }

First test: failed

return error:

1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Lack of local verification certificate cd into /etc/ssl/certs and find that it is empty, then

curl http://curl.haxx.se/ca/cacert.pem -o ./cacert.pem

Add the default cacert.pem, then add it to php.ini openssl.cafile=/etc/ssl/certs/cacert.pem, and then run the code

Second test: failed

return error:

1. OpenSSL Error messages:
error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

The first thought that the handshake failed should be the certificate error. It is estimated that the push certificate was not read. Change the certificate address to the following

stream_context_set_option($ctx, 'ssl', 'local_cert', __DIR__.'/cert/push.pem');

run again

Third test: failed

return error:

pack(): Type H: illegal hex digit z

The problem with the certificate is over, but this should be a problem with the code. The code is copied from the Internet, and I haven't looked at it. Change it to the following:

$msg = chr(0) . pack('n', 32) . pack('H*', str_replace(' ', '', sprintf('%u', CRC32($deviceToken)))) . pack('n', strlen($payload)) . $payload;

run again

Fourth test: success

Final code:

    function send(){
    	$deviceToken = 'xxx';
		$ctx = stream_context_create();
        // ck.pem is your certificate file
        stream_context_set_option($ctx, 'ssl', 'local_cert', __DIR__.'/cert/push.pem');
        stream_context_set_option($ctx, 'ssl', 'passphrase', self::$passphrase);
        // stream_context_set_option($ctx, 'ssl', 'extensions', 'ssl_client');

        // 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);

        $data['mtitle'] = 'test';
        $data['mdesc'] = 'hello world';

        // 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*', str_replace(' ', '', sprintf('%u', CRC32($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)
            var_dump('Message not delivered' . PHP_EOL);
        else
            var_dump('Message successfully delivered' . PHP_EOL);
    }

The code of Testcase will not be posted, and then go to see if the IOS side can receive it, bye.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325481664&siteId=291194637