This is late night. I just spent 10 hours searching and experimenting on google / stackoverflow. And it seems that I hate Apple Push Notifications. I am completely disappointed and would appreciate any help.
Thanks.
Problem:
The PHP code for sending Apple Push Notifications, which worked successfully two weeks ago, stops working and causes the following errors:
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/...
He stopped to work on two separate servers that use separate scripts to send APNs.
Environment:
Servers: CentOS 6.5 with PHP 5.4.32 and Ubuntu 14.04.3 with PHP 5.5.9
APN: In Production Mode
Certificates: verified using 700 + push notifications.
One of the servers uses https://github.com/immobiliare/ApnsPHP , the other uses https://github.com/antongorodezkiy/wp-apn , I tested a simple file on localhost without using third-party code.
Study:
For all cases below, I used the same active device token and the same PEM certificate of production.
Php
However, even this simple code does not work on both servers and localhost and returns the same error as above:
$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);
I also tried playing with stream_context_set_option() parameters, including entrust_2048_ca.cer , etc., and even some of the options from this article . Although the provided code worked without any changes until August 2015.
Openssl
The connection is made using openssl ( link ):
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
And received with CONNECTED(00000003) and Verify return code: 0 ( ok ) .
telnet
The connection works with telnet:
-sh-4.1$ telnet gateway.push.apple.com 2195 Trying 17.172.233.150... Connected to gateway.push.apple.com.
He did not send a push notification . I just tried using the sample code , but got an Invalid token error. The token is active and the same token that I used everywhere, as well as for Houston and Ruby.
He worked with Houston.
apn push "0346a53f...231d9d6abe11" -c /absolute/path/to/apn_prod.pem -m "Hello from the command line!" -e "production"
ruby
I'm not a Ruby programmer (at least), but after success in Houston, I found and adapted Ruby code without dependency on Houston.
And he worked :
#!/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"
Questions:
- What is wrong with PHP? Is there any kind of error related to this problem? (I did not find an error report, though)
- Any ideas how to solve this problem?
- Any ideas what could be the difference in PHP and Ruby cases (I suppose Python or Perl can work fine too)? I even tried to read PHP sources, but to no avail to understand how
stream_socket_client() implemented.
Please, help.