代码之家  ›  专栏  ›  技术社区  ›  rickharrison

为什么只有一些设备接收推送通知

  •  4
  • rickharrison  · 技术社区  · 14 年前

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

    我做错什么了吗?PHP不能处理数千次循环和连接上的流消息吗?

    3 回复  |  直到 14 年前
        1
  •  5
  •   Ed209    13 年前

    除了其他人已经提出的建议之外,这里还有一个清单,列出了当推不起作用时需要考虑的事项。

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

    希望这有帮助。

        2
  •  1
  •   MrCranky    14 年前

    我认为这里有三个潜在的问题:

    1) 你连接的次数太多(可能比你想象的要多),而苹果拒绝/放弃连接是因为它认为你太垃圾了。老实说,这是很明显的——你的fwrite会失败,因为小溪会死的。

    2) 你没有做任何错误检查。请参阅APNS指南,但它可能会沿着与错误响应相同的连接进行响应,而您只是忽略了这一点。我认为每次循环时,您都应该检查是否有要读取的数据,读取它并将其解释为错误响应包。至少你应该把错误响应记录下来。

    3) 这是一个很长的机会。有没有可能你真的删除了这些用户,也许是因为反馈服务让你这么做的?如果用户已断开连接很长一段时间,服务将无法发送通知,它可能会告诉您从列表中删除这些设备。如果你在应用程序启动时没有重新订阅那些用户(或者至少确认他们仍然订阅了),那么他们会认为他们订阅了通知,而实际上你已经选择忘记他们。

        3
  •  0
  •   Beaker    14 年前

    隐马尔可夫模型。。。我看没有什么问题。客户端真的为你的应用启用推送通知了吗?