30

就您如何查询而言,有人可以澄清 APNs(Apple Push Notification)想要什么吗?

文档说,一旦建立连接,它就会开始发送。这是否意味着我不fread()对它做一个?

这是我当前尝试阅读的代码。我没有把它fread()放在一个循环中,因为我不知道什么响应表明“没有更多的记录要读取”并且我不希望我的服务器上出现无限循环。

<?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()的方法是错误的。

谢谢

4

5 回答 5

69

Here's a big gotcha which confused me when I first tried connecting: the APNS feedback servers only return the device tokens that have "expired" since your last feedback request. Which means most of the time you'll get a NULL response unless you're already dealing with a high volume of users of your app.

So make sure you store the expired device tokens to disk or db, because after your feedback query they're gone for good. This makes testing a pain to say the least!

Here's a complete function to fetch the device tokens from the APNS feedback servers (many thanks to the answers above for helping me put it all together):

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;
}

If all is well, the return values from this function will look something like this (via print_r()):

Array
(
    Array
    (
        [timestamp] => 1266604759
        [length] => 32
        [devtoken] => abc1234..............etcetc
    ),
    Array
    (
        [timestamp] => 1266604922
        [length] => 32
        [devtoken] => def56789..............etcetc
    ),
)
于 2010-02-19T19:08:58.333 回答
2

该代码看起来正确,但是您需要循环并检查流的结尾才能读取所有设备代码。

 while (!feof($apns)) {
        $devcon = fread($apns, 38);
 }

但是我的问题是数据的实际解包。有谁知道如何解压您刚刚读取的二进制数据以获取实际的设备 ID(作为字符串)以及时间戳等?

于 2009-10-14T15:04:24.570 回答
1

我从苹果论坛得到了解决方案,它是用于开发的。也试试这个用于生产。

“好吧,尽管听起来很愚蠢,但我找到了一个解决方案:

在程序门户中创建一个虚拟应用程序 ID,在其上启用开发推送通知创建并下载关联的配置文件创建一个新的 xcode 项目,并在启动时调用 registerForRemoteNotificationTypes 方法。在您的设备上安装虚拟应用程序。此时,您的设备上应该运行了两个 DEVELOPMENT 应用程序:原始应用程序和虚拟应用程序。两者都应该注册以接收推送通知。卸载原始应用程序,并尝试向该应用程序发送推送通知。调用反馈服务,您应该会收到返回的数据。”

于 2009-10-05T11:49:45.167 回答
0

这终于对我有用。

$arr = unpack("H*", $devconts); 
$rawhex = trim(implode("", $arr));

$feedbackTime = hexdec(substr($rawhex, 0, 8)); 
$feedbackDate = date('Y-m-d H:i', $feedbackTime); 
$feedbackLen = hexdec(substr($rawhex, 8, 4)); 
$feedbackDeviceToken = substr($rawhex, 12, 64);

然后您只需根据时间戳检查设备令牌!

于 2009-10-15T20:50:52.680 回答
0

刚开始使用这个库 - 对我很有用!

https://github.com/mac-cain13/notificato

于 2016-02-19T06:59:47.970 回答