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.