今天早上发现app的通知突然就发送失败了,之前一直都是正常的,真是郁闷,就马上下载代码调试,花费了大半天的时间调试发现尽然是push的证书过期了,最后叫ios的同事重新生成证书就可以解决了。 现在总结一下调试过程中遇到的问题和解决的方法,希望对大家有帮助。
一、发送push 的文字过长导致发送不成功,
$playlod= chr(0) . pack("n",32) . pack("H*", $deviceToken) . pack("n",strlen($payload)) . $payload 这一段的解析后长度不能大于255个字节,大于255个字节就会被苹果的服务器拒绝导致发送失败。
解决方案:修改文字的长度,中文字符占两个字符大概在35个字就可以了
二、由于应用证书过期导致发送失败(最常见),通常证书有效期半年就要更换一次了
Warning: stream_socket_client() [function.stream-socket-client]: SSL operation failed with code 1. OpenSSL Error messages: error:14094415:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate expired in Warning: stream_socket_client() [function.stream-socket-client]: Failed to enable crypto in Warning: stream_socket_client() [function.stream-socket-client]: unable to connect to ssl://gateway.push.apple.com:2195 (Unknown error) in
解决方案:找ios的同事更新并上传对应的应用的证书
三、无效的Devictoken的解决方法
We have solved this problem. It is broken due to invalid tokens in our database table.And apple apns service will disconnect us if there is an invalid token. Since the connection is broken, it will have "Broken Pipe" error when you try to send messages again. Basic solution is to find whether writing to pipe is successful, if not, just disconnect and reconnect again after some delay.
解决方案:判断发送是否成功,如果不成功,要先断开,重连,再继续发后面的
四、链接苹果的APNS 服务器失败,服务器不能连接到ssl://gateway.push.apple.com:2195,服务器telnet不通这个域名,出现报错未找到地址。
Warning: stream_socket_client() [function.stream-socket-client]: unable to connect to ssl://ssl://gateway.push.apple.com:2195 (Failed to parse address "ssl://gateway.push.apple.com:2195")
解决方法:更改linun服务器的dns。路径 vi /etc/resolv.conf 在后面加上下面两个通用谷歌dns
nameserver 8.8.8.8 #google域名服务器
nameserver 8.8.4.4 #google域名服务器
加两行加完重启下phpcgi 让它立即生效
五、(写入苹果APNS失败)Failed writing to stream." 连接上了,没有写入到苹果的apns服务器
解决方法: 一、检查devictoken是否有效,二、有可能用户卸载了该应用也可能导致写入失败
六、APNS responded with command($command) status($status) pid($identifier). 连接上了,写入的失败返回的二进制流, $status 这个变量的值就是对应下面的返回码
Push ;返回的状态码:
0 No errors encountered (通知成功)
1 Processing error (进程错误)
2 Missing device token (devictoken 错误)
3 Missing topic
4 Missing payload (发送通知的格式错误,正确是json格式)
5 Invalid token size (devictoken的长度不对,正确是utf-8 编码的64 位)
6 Invalid topic size
7 Invalid payload size (发送通知的格式的大小,正确是255个字节内)
8 Invalid token (无效的 devictoken)
255 None (unknown) (未知状态)
返回的对应错误,进行相对应的修改就可以了。
七、 apns链接失败,报错的内容如下,是连接超时,超过socket限定值的值就会出现无法链接情况
Warning: stream_socket_client() [function.stream-socket-client]: unable to connect to ssl://gateway.push.apple.com:2195 (由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 )
Alert error: Maximum execution time of 60 seconds exceeded in
解决的方法:首先确认服务器能不能ping通苹果的APNS的URL,看是不是dns设置出问题
八、 证书不正确导致链接失败,证书是有分正式证书和测试证书两个
报错Warning: stream_socket_client() [function.stream-socket-client]: Unable to set local cert chain file `ck.pem'; Check that your cafile/capath settings include details of your certificate and its issuer in F:\FTPHome\LocalUser\AppUse\SimplePush\simplepush.php on line 19Warning: stream_socket_client() [function.stream-socket-client]: failed to create an SSL handle in F:\FTPHome\LocalUser\AppUse\SimplePush\simplepush.php on line 19Warning: stream_socket_client() [function.stream-socket-client]: Failed to enable crypto in
解决的办法: 是重新生成正确的证书,用于正式版或者测试版,生成证书需要找ios的同事配合
九、 服务器的php配置错误,ssl配置错误
Warning: stream_socket_client() [function.stream-socket-client]: Unable to set private key file `D:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zcy\cer.pem' in D:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zcy\APNSSender.php on line 25 Warning: stream_socket_client() [function.stream-socket-client]: failed to create an SSL handle in D:\Program Files\Apache Software Foundation\Apache2.2\htdocs\zcy\APNSSender.php on line 25
解决的方法:
1,首先把PHP目录下面的ssleay32.dll和libeay32.dll到 windows下的system32目录下
2,修改PHP.ini,开启extension=php_openssl.dll
3,重启web服务器
十、 服务器的网关出错,链接不上苹果的apns 服务器
Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure in E:\......\Index.php on line 106 Warning: stream_socket_client(): Failed to enable crypto in E:\......\Index.php on line 106 Warning: stream_socket_client(): unable to connect to ssl://gateway.push.apple.com:2195 (Unknown error) in E:\......\Index.php on line 106
解决方法:重新设置网关(更改服务器dns 同上更改dns),重启php或者换一台网关正常的服务器。
十一、网络错误链接失败
Warning: stream_socket_client() [function.stream-socket-client]: php_network_getaddresses: getaddrinfo failed: ²»ÖªµÀÕâÑùµÄÖ÷»ú¡£ in D:\wamp\www\iospush\Public\php\Apns.Class.php on line 163 Warning: stream_socket_client() [function.stream-socket-client]: unable to connect to ssl://gateway.push.apple.com:2195 (php_network_getaddresses: getaddrinfo failed: ²»ÖªµÀÕâÑùµÄÖ÷»ú¡£ ) in D:\wamp\www\iospush\Public\php\Apns.Class.php on line 163
解决方法: 检查网络是否正常和dns是否正常使用,看看防火墙是否屏蔽了
十二、检验证书是否正确的方法
[root@iZ23ssz3sgmZ ~]# telnet gateway.push.apple.com 2195 Trying 17.110.226.221... Connected to gateway.push.apple.com (17.110.226.221). Escape character is '^]'. h h Connection closed by foreign host.
它将尝试发送一个规则的,不加密的连接到APNS服务。如果你看到上面的反馈,那说明你的win/linux/mac能够到达APNS。按下Ctrl+C 关闭连接。如果得到一个错误信息,那么你需要确保你的防火墙允许2195端口。
最后我们使用linux 系统的openssl 来测试证书都是正确,这次用我们的SSL证书和私钥来设置一个安全的连接,
#证书路径,如果有密码就用 -key PushChatKey.pem
Enter pass phrase for PushChatKey.pem:
[root@iZ23ssz3sgmZ ~]# openssl s_client -connect gateway.push.apple.com:2195 -cert ck.pem CONNECTED(00000003) depth=2 /O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048) verify return:1 depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C verify return:1 depth=0 /C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.push.apple.com verify return:1 30482:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:188:
上面这个是连接错误,出现报错,说明这个证书是错误的,请重新更新证书就可以了。
正确的应该是:
[root@iZ23ssz3sgmZ ~]# openssl s_client -connect gateway.push.apple.com:2195 -cert push/pailixiu.pem CONNECTED(00000003) depth=2 /O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048) verify return:1 depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C verify return:1 depth=0 /C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.push.apple.com verify return:1 --- Certificate chain 0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.push.apple.com i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C 1 s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048) --- Server certificate -----BEGIN CERTIFICATE----- MIIFIzCCBAugAwIBAgIETCMvvjANBgkqhkiG9w0BAQUFADCBsTELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 Lm5ldC9ycGEgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW KGMpIDIwMDkgRW50cnVzdCwgSW5jLjEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZp Y2F0aW9uIEF1dGhvcml0eSAtIEwxQzAeFw0xNDA1MjgxNjM2NDJaFw0xNjA1MjQw NTMwMjlaMGwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYD VQQHEwlDdXBlcnRpbm8xEzARBgNVBAoTCkFwcGxlIEluYy4xHzAdBgNVBAMTFmdh dGV3YXkucHVzaC5hcHBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQDnJcppPszTRZIuOV1rpI7wXu3ZzViII9dLJupnXP7wRiQv1cLxX+cn0FD3 tPghn8o45BF5Xx41jWrddLWfy+78MvhjVwWnkgB1UmuH1PPDCCU2xoNb4ugN9vEQ MTbIRfQOfBpf6B3jvtQIsN2V+XnSnoXZgLItsO5dhR6nphrI1aU3l+rbBqPq3Dh0 gj+j7/NUaUZL3Hy4QyCywxnE7wacoZgmZxNnTbQqXswWpz/BNy6Qh7odaDEfnPCH ILdFjmrmj1cQiQicvZ1WguqJLWLiy4DQH3b5Wvg2znnFvHwZZoqHjsIzb28sZXKb fUYDG4Oc6LvQoDTBbHrTIqqE7qMtAgMBAAGjggGFMIIBgTALBgNVHQ8EBAMCBaAw HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDMGA1UdHwQsMCowKKAmoCSG Imh0dHA6Ly9jcmwuZW50cnVzdC5uZXQvbGV2ZWwxYy5jcmwwZAYIKwYBBQUHAQEE WDBWMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAvBggrBgEF BQcwAoYjaHR0cDovL2FpYS5lbnRydXN0Lm5ldC8yMDQ4LWwxYy5jZXIwSgYDVR0g BEMwQTA1BgkqhkiG9n0HSwIwKDAmBggrBgEFBQcCARYaaHR0cDovL3d3dy5lbnRy dXN0Lm5ldC9ycGEwCAYGZ4EMAQICMCEGA1UdEQQaMBiCFmdhdGV3YXkucHVzaC5h cHBsZS5jb20wHwYDVR0jBBgwFoAUHvGriQb4SQ8BM3fuFHruGXyTKE0wHQYDVR0O BBYEFLPbpY42wi/c+pWkIZynOUxObmvMMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEF BQADggEBAIQ+j1Jw6FLDc3/6kEoCfAT1CGAkrhHM/bgAzXn0ZoBU6U099Hmy5g3s vg6vS22wnjiBfV6lGqdYcdQKXxwasm6YatDHpooOheZyvyZ/n+o4FPFzPmINX+jz Y/CFHRuEIcFuTzt5MxbuovnChy1eNy5hBXXEAcsvcSnFeTTDbZ7KF7Whi2jhwVRt mAijOu3s06E4qiKbjLjDYq8k5U/ZK0kGGJW6R2DEjZEf8/Yw/UnrCyGC9KpYkajx UYtIJAwKTNopVQn/nEIUNt6W7IPBER1Pb+fDBCJfaUOwr8AYN/TsM0MKGMaqyeGn de7tGJEmdBgmtX2Wn0r0Erg+9nnjOEQ= -----END CERTIFICATE----- subject=/C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.push.apple.com issuer=/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C --- Acceptable client certificate CA names /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA /C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority /C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Application Integration Certification Authority --- SSL handshake has read 3144 bytes and written 2358 bytes --- New, TLSv1/SSLv3, Cipher is AES256-SHA Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : AES256-SHA Session-ID: Session-ID-ctx: Master-Key: 4026B8903B655E42FD3BEE15E3ED35C518761A7262C269FF772257C31B999DD96757FE2DC8AA5897091662EAA37F310B Key-Arg : None Krb5 Principal: None Start Time: 1459567195 Timeout : 300 (sec) Verify return code: 0 (ok) --- f closed
上面表示证书是正确的,#证书路径,如果有密码就用
openssl s_client -connect gateway.push.apple.com:2195 -cert push/pailixiu.pem -key PushChatKey.pem Enter pass phrase for PushChatKey.pem
你会看到一个完整的输出,让你明白OpenSSL在后台做什么。如果连接是成功的,你可以键入一些字符。当你按下回车后,服务就会断开连接。如果在建立连接时有问题,OpenSSL将会给你一个错误消息,但是你不得不向上翻输出LOG,来找到它。
当然上面要测试prodution版本是否正确的话,把gateway.sandbox.push.apple.com换成gateway.push.apple.com就好。