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

Php 为什么只有一些设备接收推送通知,php,iphone,push-notification,apple-push-notifications,Php,Iphone,Push Notification,Apple Push Notifications,我设置了一个推送通知服务,根据RSS提要向客户端发送通知。我有一个服务,每分钟运行一次,看看是否有新的帖子被添加到提要中。如果是这样,服务将向所有客户端发送通知。然而,一些人抱怨说他们没有收到任何推送通知。以下是我用来发送消息的函数: function _sendMessages($tokens, $message) { $payload['aps'] = array('alert' => $message, 'sound' => 'default');

我设置了一个推送通知服务,根据RSS提要向客户端发送通知。我有一个服务,每分钟运行一次,看看是否有新的帖子被添加到提要中。如果是这样,服务将向所有客户端发送通知。然而,一些人抱怨说他们没有收到任何推送通知。以下是我用来发送消息的函数:

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不能处理数千次的for循环和通过连接传输消息吗?

嗯。。。我看不出有什么问题。客户端真的为你的应用启用推送通知了吗?

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

1你连接的频率太高,可能比你想象的要高,苹果拒绝/放弃连接是因为它认为你太垃圾了。老实说,这是很明显的——你的写操作会失败,因为流已经死了

理想情况下,像连接保持打开10分钟一样,APN是我们使用的非活动超时,而不是每分钟重新建立一次。SSL协商需要CPU,但保持打开的连接相对便宜。所以,如果可以的话,我会在两次运行之间保持连接打开,如果由于任何原因被删除,我会自动重新建立连接

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


3.这一次机会不大。你是否真的删除了这些用户,也许是因为反馈服务让你这么做?如果用户已断开连接很长时间,服务将无法发送通知,它可能会告诉您从列表中删除这些设备。如果你不重新订阅这些用户,或者至少在应用程序启动时确认他们仍然订阅,那么他们会认为他们订阅了通知,而实际上你已经选择忘记他们如果您的推送数据包总数超过256字节,包括初始头、令牌和JSON负载,APNS将直接丢弃它。如果您没有使用高级错误检测,您将永远不会知道,直到您的用户开始抱怨。你要做的是检查编码的数据包大小,也就是说,你将要传输的实际数据的大小,如果超过256字节,要么拒绝它,要么切断一些消息文本并再次编码,直到它是“是”,MySQL数据库表有几千行带有设备令牌的条目。好的,他们可以稍后禁用它们。我已经浏览了很多通知,从未遇到过丢弃邮件的问题。我唯一一次遇到问题是,如果用户进入他们的设置并禁用了我的应用程序的通知。用PHP保持两次尝试之间的连接的最佳方式是什么?这实际上取决于服务器进程的设置方式,但基本上需要在调用_sendmages之间持久化$apns对象。也就是说,将连接的构造移动到其自身的功能中,并将其传递到_sendmages中。然后,仅在$apns对象不存在时构造它。但我们不知道您是否有一个持续运行的服务脚本或其他东西。我们将我们的服务作为一项服务运行,因此有一个循环和计时器来检查a是否有任何需要发送的通知,或者b连接已空闲X分钟,应该关闭。