Это поздно ночью. Я только что провел 10 часов в поиске и экспериментах google / stackoverflow. И, кажется, я ненавижу Apple Push-уведомления. Я полностью расстроен и буду признателен за любую помощь.
Спасибо.
PHP-код для отправки Apple Push-уведомлений, который успешно работал две недели назад, перестал работать и выдает следующие ошибки:
PHP Warning: stream_socket_client(): Failed to enable crypto in /home/...
PHP Warning: stream_socket_client(): unable to connect to ssl://gateway.push.apple.com:2195 (Unknown error) in /home/...
Он перестал работать на двух отдельных серверах, которые используют отдельные сценарии для отправки APN.
Серверы: CentOS 6.5 с PHP 5.4.32 и Ubuntu 14.04.3 с PHP 5.5.9
APN: в производственном режиме
Сертификаты: протестировано с 700+ push-уведомлениями.
Один из серверов использует https://github.com/immobiliare/ApnsPHP, Другой — https://github.com/antongorodezkiy/wp-apn, на локальном хосте я тестировал простой файл без использования стороннего кода.
Для всех описанных ниже случаев я использовал один и тот же токен активного устройства и один и тот же производственный сертификат PEM.
Тем не менее, даже этот простой код не работает на обоих серверах и на локальном хосте и возвращают ту же ошибку, что и выше:
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', '/absolute/path/to/apn_prod.pem');
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
Я также пытался играть с stream_context_set_option()
варианты, включают entrust_2048_ca.cer
и т.д., и даже некоторые варианты из Эта статья. Хотя предоставленный код работал без каких-либо изменений до августа 2015 года.
Соединение сработало с openssl (ссылка на сайт):
openssl s_client -connect gateway.push.apple.com:2195 -cert /absolute/path/to/apn_prod.pem -debug -showcerts -CAfile /absolute/path/to/server-ca-cert.pem
И получил с CONNECTED(00000003)
а также Verify return code: 0 ( ok )
,
Соединение сработало с телнетом:
-sh-4.1$ telnet gateway.push.apple.com 2195
Trying 17.172.233.150...
Connected to gateway.push.apple.com.
Не отправлено push-уведомление. Я просто пытался использовать адаптацию образец кода, но получил ошибку Invalid token
, Токен активен и тот же токен, который я использовал везде, а также для Хьюстона и Руби.
Это сработало с Хьюстоном
apn push "0346a53f...231d9d6abe11" -c /absolute/path/to/apn_prod.pem -m "Hello from the command line!" -e "production"
Я не программист на Ruby (пока, по крайней мере), но после успеха в Хьюстоне я нашел и адаптировал код Ruby без зависимости от Хьюстона.
А также это сработало:
#!/usr/bin/env ruby
require 'openssl'
require 'socket'
require 'json'
token = "0346a53f...231d9d6abe11"cert = File.read("/absolute/path/to/apn_prod.pem")
ctx = OpenSSL::SSL::SSLContext.new
ctx.key = OpenSSL::PKey::RSA.new(cert, '') #set passphrase here, if any
ctx.cert = OpenSSL::X509::Certificate.new(cert)
sock = TCPSocket.new('gateway.push.apple.com', 2195) #development gateway
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
ssl.connect
payload = {"aps" => {"alert" => "Oh hai!", "badge" => 1, "sound" => 'default'}}
json = payload.to_json()
token = [token.delete(' ')].pack('H*') #something like 2c0cad 01d1465 346786a9 3a07613f2 b03f0b94b6 8dde3993 d9017224 ad068d36
apnsMessage = "\0\0 #{token}\0#{json.length.chr}#{json}"ssl.write(apnsMessage)
ssl.close
sock.close
puts "End"
stream_socket_client()
реализованы.Я нашел проблему и исправил ее.
проблема был в .pem сертификате. Каким-то образом в одном файле было два сертификата для файлов производства и разработки .pem. Один и тот же файл .pem с двумя сертификатами долгое время находился в репо, но APN перестали работать только несколько месяцев назад. Может быть, что-то было обновлено / изменено на стороне Apple.
Я предполагаю, что код Ruby каким-то образом удаляет дублирование сертификатов или, возможно, он потребовал только первый сертификат, поэтому он работал в Ruby.
Тем не менее решение должен был удалить второй сертификат из файла .pem. После этого APN начали работать, и теперь они работают (некоторые я получил только вчера).
Если вы просто повторно используете старый запрос на подпись сертификата (CSR), обязательно удалите устаревший / старый сертификат APNs из цепочки для ключей, прежде чем экспортировать новый и его закрытый ключ в виде файла p12. Если вы этого не сделаете, файл PEM, сгенерированный вами из экспортированного p12, все равно будет содержать устаревший / старый сертификат, который не подходит для Apple Push-провайдера. Таким образом, в результате чего unable to connect to ssl...
,