iOS 应用程序推送通知

iOS application push notifications

我们在 PHP 中内置了一个应用程序,可以向 Android 和 iOS 发送推送通知。我们的问题是 iOS 的某些设备 ID 似乎完全停止了我们脚本中所有其他 iOS 推送通知的发送,他们甚至说它们已无误发送但它停止了所有之后在循环中通知。

如果我们随后从数据库中删除有问题的设备 ID,则发送脚本适用于在有问题的设备之后的所有设备。这很奇怪,似乎无法弄清楚为什么。

有没有人有这方面的经验?发送到一个不再存在的设备 ID 是否会阻止苹果在该特定连接上完成我们的脚本?

这是我们在 PHP 中的发送脚本(这适用于除了奇怪的恶意设备 ID 之外的所有设备):

    $tHost = 'gateway.push.apple.com';
    $tPort = 2195;
    $tCert = "path_to_our_cert.pem";
    $tPassphrase = 'passphrase';

    $tAlert = $this->title; //assign a title
    $tBadge = 8;
    $tSound = 'default';
    $tPayload = $this->body_plain; //assign a body

            // Create the message content that is to be sent to the device.
    $tBody['aps'] = array ('alert' => $tAlert,'badge' => $tBadge,'sound' => $tSound,);
    $tBody ['payload'] = $tPayload;
    $tBody = json_encode ($tBody);

    $tContext = stream_context_create ();
    stream_context_set_option ($tContext, 'ssl', 'local_cert', $tCert);
    stream_context_set_option ($tContext, 'ssl', 'passphrase', $tPassphrase);
    $tSocket = stream_socket_client ('ssl://'.$tHost.':'.$tPort, $error, $errstr, 30, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $tContext);   

    if (!$tSocket) exit ("APNS Connection Failed: $error $errstr" . PHP_EOL);
    //Loop through all devices to send
    foreach($this->device->devices as $item){
        if($item->os != "iOS") continue;                
        if(session::getAdministratorStaffSchoolID() != $item->school_id) continue;
        $tToken = $item->device_id;//assign the device id
        $tMsg = chr (0) . chr (0) . chr (32) . pack ('H*', $tToken) . pack ('n', strlen ($tBody)) . $tBody;
            $tResult = fwrite ($tSocket, $tMsg, strlen ($tMsg));
    }

    fclose ($tSocket);

有没有人对此有任何想法?

非常感谢

AFAIK APNs 将在发生任何错误(无效的设备令牌、格式错误的有效负载等)时立即关闭连接。您发送 Push 的代码需要准备好从这种情况中恢复,重新连接然后重新开始工作。

查看那里的 3rdParty 库来为您执行这项工作。您将依赖社区工作。

我可以推荐Pushy写在Java。我已经在 2 个不同的项目中使用过它,我可以说它工作正常并且它是一个非常活跃的项目(那里有很多讨论和更新)。

我不知道他们中有谁在使用 PHP,但可能有一个

所以,只是一个想法,但您正在使用旧格式发送通知:

$tMsg = chr (0) . chr (0) . chr (32) . pack ('H*', $tToken) . pack ('n', strlen ($tBody)) . $tBody;

并且:

Error response. With the legacy format, if you send a notification packet that is malformed in some way—for example, the payload exceeds the stipulated limit—APNs responds by severing the connection. It gives no indication why it rejected the notification. The enhanced format lets a provider tag a notification with an arbitrary identifier. If there is an error, APNs returns a packet that associates an error code with the identifier. This response enables the provider to locate and correct the malformed notification.

https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Appendixes/LegacyFormat.html

所以也许 APNS 只是断开了您的连接?这就是为什么所有剩余的通知实际上都没有通过的原因。仔细看看这些有效载荷。可能是转向新格式的好时机。