为什么只有部分设备接收推送通知

ric*_*son 4 php iphone push-notification apple-push-notifications

我设置了推送通知服务,以根据RSS源向客户发送通知.我有一个每分钟运行一次的服务,看看是否有新帖子添加到Feed中.如果是这样,该服务将向所有客户发送通知.但是,有些人一直在抱怨说他们没有收到任何推送通知.这是我用来发送消息的功能:

function _sendMessages($tokens, $message) {
        $payload['aps'] = array('alert' => $message, 'sound' => 'default');
        $payload = json_encode($payload);

        $context = stream_context_create();
        stream_context_set_option($context, 'ssl', 'local_cert', $this->certificate);
        stream_context_set_option($context, 'ssl', 'passphrase', '*********');

        $apns = stream_socket_client('ssl://' . $this->server . ':' . $this->port, $error, $errorString,60, STREAM_CLIENT_CONNECT, $context);

        foreach($tokens as $row) {
            $apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $row->device_token)) . chr(0) . chr(strlen($payload)) . $payload;
            $fwrite = fwrite($apns, $apnsMessage);

            if (!$fwrite) echo 'push error';
            else echo 'push success';
        }

        fclose($apns);
    }
Run Code Online (Sandbox Code Playgroud)

我做错了吗?PHP无法处理数千次循环并通过连接传输消息吗?

小智 5

除了其他人已经提出的建议之外,这里是推送不起作用时要考虑的事项清单.

  1. 如果您的总推送数据包超过256个字节,包括初始标头,令牌和JSON有效负载,APNS将简单地丢弃它.如果您没有使用"高级"错误检测,您将永远不会知道,直到您的用户开始抱怨.你需要做的是检查编码的数据包大小,即你将抽取线路的实际数据的大小,如果它超过256字节,要么拒绝它,要么切断一些消息文本和编码再一次,直到<= 256字节长.
  2. 如果您的有效负载有任何问题,包括长度,APNS将丢弃它,APNS也将丢弃您的连接.
  3. 如果您有持久连接,并且它闲置大约20分钟左右,APNS将默默地断开连接.你必须为此做好准备并重新连接.
  4. 如果您的APNS证书已过期或不正确,并且您继续尝试以过高的速率连接,APNS将在未知的时间段内将您的IP地址列入黑名单,但它会超过几分钟,甚至一小时或更长时间.
  5. 如果iPhone没有3G接收,但确实有WiFi,它会尝试将其用于推送通知.如果您所在的防火墙区域不允许与Apple网络的出站连接,则您的iPhone将无法打开到APNS的套接字而您是SOL.
  6. 每次客户端连接到APNS时,我不确定您的SQL DB是否使用推送令牌进行更新.拥有一个推送令牌的静态数据库是一个问题,因为推送令牌永远不会保持不变 - 它甚至在APNS编程指南中都这样说.iPhone应该在每次启动时获取推送令牌,并将其传送到服务器端(我相信你可以优化它 - iPhone可以持久存储最后一个令牌并仅在它已经改变时发送它).但有些事情会导致推送令牌发生变化,例如重新注册iPhone以进行推送,而我不确定还有什么.我所知道的是,依赖推送令牌就像一个GUID就是在寻找麻烦.下次令牌更改时,如果您的数据库未更新,请再次推送到该客户端.

希望这可以帮助.