PHP技术来查询APNs反馈服务器
有人可以澄清什么APNs(苹果推送通知)要求您如何查询它?
文档说,一旦build立连接就开始发送。 这是否意味着我不做一个fread()
呢?
这是我目前的代码来尝试阅读它。 我没有把fread()
放在一个循环中,因为我不知道什么响应表示“没有更多的logging要读取”,我不希望在我的服务器上出现无限循环。
<?php $apnsCert = 'HOHRO-prod.pem'; $streamContext = stream_context_create(); stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert); stream_context_set_option($streamContext, 'ssl', 'verify_peer', false); $apns = stream_socket_client('ssl://feedback.push.apple.com:2196', $error, $errorString, 60, STREAM_CLIENT_CONNECT, $streamContext); echo 'error=' . $error; echo 'errorString=' . $errorString; $result = fread($apns, 38); echo 'result=' . $result; fclose($apns); ?>
到目前为止,我所得到的是一个空回复。 没有错误,所以它正在连接。
我不知道是否空回答意味着没有数据,或者我的fread()
是做错的方法。
谢谢
以下是我第一次尝试连接时遇到的困扰:APNS反馈服务器只会返回自上次反馈请求以来 “已过期”的设备令牌。 这意味着大多数情况下你会得到一个NULL响应,除非你已经处理了大量的应用程序用户。
因此,请确保将过期的设备标记存储到磁盘或分贝,因为在您的反馈查询后,它们已经消失。 这使得testing痛苦至less可以说!
这是一个完整的function,从APNS反馈服务器获取设备令牌(很多感谢上面的答案,帮助我把它们放在一起):
function send_feedback_request() { //connect to the APNS feedback servers //make sure you're using the right dev/production server & cert combo! $stream_context = stream_context_create(); stream_context_set_option($stream_context, 'ssl', 'local_cert', '/path/to/my/cert.pem'); $apns = stream_socket_client('ssl://feedback.push.apple.com:2196', $errcode, $errstr, 60, STREAM_CLIENT_CONNECT, $stream_context); if(!$apns) { echo "ERROR $errcode: $errstr\n"; return; } $feedback_tokens = array(); //and read the data on the connection: while(!feof($apns)) { $data = fread($apns, 38); if(strlen($data)) { $feedback_tokens[] = unpack("N1timestamp/n1length/H*devtoken", $data); } } fclose($apns); return $feedback_tokens; }
如果一切正常,这个函数的返回值就像这样(通过print_r()):
Array ( Array ( [timestamp] => 1266604759 [length] => 32 [devtoken] => abc1234..............etcetc ), Array ( [timestamp] => 1266604922 [length] => 32 [devtoken] => def56789..............etcetc ), )
该代码看起来是正确的,但是您需要循环并检查stream结束以读取所有设备代码。
while (!feof($apns)) { $devcon = fread($apns, 38); }
然而我的问题是实际的数据解包。 有谁知道如何解压缩刚刚读取的二进制数据以获得实际的设备ID(string)以及时间戳等?
我从苹果论坛得到了解决scheme,这是为了开发。 试试这也用于生产。
“好吧,听起来很愚蠢,我find了一个解决办法:
在程序门户中创build一个虚拟应用程序ID,在其上启用开发推送通知创build并下载关联的供应configuration文件创build一个新的xcode项目,并在启动时调用registerForRemoteNotificationTypes方法。 在您的设备上安装虚拟应用程序。 此时,您应该在设备上运行两个“开发”应用程序:原始应用程序和虚拟应用程序。 两者都应该注册以接收推送通知。 卸载原来的应用程序,并尝试发送推送通知到该应用程序。 调用反馈服务,你应该收到数据。“
这终于为我工作。
$arr = unpack("H*", $devconts); $rawhex = trim(implode("", $arr)); $feedbackTime = hexdec(substr($rawhex, 0, 8)); $feedbackDate = date('Ymd H:i', $feedbackTime); $feedbackLen = hexdec(substr($rawhex, 8, 4)); $feedbackDeviceToken = substr($rawhex, 12, 64);
然后你只需根据时间戳检查设备标记!
刚开始使用这个库 – 对我很好用!