为什么只有部分设备会收到推送通知
我设置了一个推送通知服务,根据 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 循环并通过连接传输消息吗?
I set up a push notification service to send out notifications to clients based on an RSS feed. I have a service that runs every minute to see if a new post was added to the feed. If so, the service will send out a notification to all the clients. However, some people have been complaining saying that they are not receiving any push notifications. Here is the function that I use to send out the messages:
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);
}
Am I doing anything wrong? Can PHP not handle going through this for loop thousands of times and streaming messages over the connection?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为这里有 3 个潜在的问题:
1)你连接太频繁(可能比你想象的更频繁),而 Apple 拒绝/放弃连接,因为它认为你太垃圾了。老实说,这是非常明显的 - 你的 fwrite 会失败,因为流会死掉。
理想情况下,APNS 会尽可能长时间地保持连接打开状态(我们使用的不活动超时时间为 10 分钟),而不是每分钟都重新建立连接。 SSL 协商会消耗 CPU 资源,但保持打开的连接相对便宜。因此,如果可以的话,我会在运行之间保持该连接打开,并在由于任何原因断开时自动重新建立它。
2)您没有进行任何错误检查。请参阅 APNS 指南,但它可能会沿着同一连接做出错误响应,而您只是忽略它。我认为每次循环时您都应该检查是否有任何数据要读取,读取它并将其解释为错误响应数据包。至少您应该记录错误响应。
3)这个机会渺茫。您是否有可能实际上已经删除了这些用户,也许是因为反馈服务告诉您这样做?如果用户长时间断开连接,服务将无法发送通知,并且可能会告诉您从列表中删除这些设备。如果您在应用程序启动时不重新订阅这些用户(或至少确认他们仍然订阅),那么他们会认为他们已订阅通知,而实际上您已经选择忘记它们。
I think there's 3 potential problems here:
1) You're connecting too often (maybe more often than you think you are), and Apple is refusing/dropping the connection because it thinks you're too spammy. That would be pretty obvious to be honest - your fwrite would fail because the stream would have gone dead.
APNS ideally like the connection held open for as long as possible (10 minutes is the inactivity timeout we use) rather than re-establishing it every minute. SSL negotiation costs CPU, but a connection being held open is relatively cheap. So I'd hold that connection open between runs if you can, and re-establish it automatically if it's been dropped for any reason.
2) You're not doing any error checking. See the APNS guide, but it may be responding back along the same connection with error responses and you're just ignoring that. I think that each time round the loop you should be checking if there's any data to read, reading it and interpreting it as an error response packet. At the very least you should be logging error responses out.
3) This one's a long shot. Is it possible that you have actually removed those users, perhaps because the feedback service told you to? If a user has been disconnected for a long time, notifications would fail to be delivered by the service, and it might tell you to remove those devices from your list. If you don't re-subscribe those users (or at least confirm that they are still subscribed) when the app launches, then they would think that they were subscribed to notifications when in fact you'd already chosen to forget about them.
嗯……我没觉得有什么问题。客户端是否真的为您的应用程序启用了推送通知?
Hmm... I don't see anything wrong with it. Did the clients actually enable push notifications for your app?
除了其他人已经提出的建议之外,这里还有推送不起作用时需要考虑的事项清单。
希望这有帮助。
Other than the suggestions already made by others, here's a checklist of things to consider when pushes don't work.
Hope this helps.