【问题标题】:Sending high volumes of notifications发送大量通知
【发布时间】:2015-12-22 11:12:18
【问题描述】:

我需要同时发送数千个(实际上是 10 000 个)推送通知,为此,我检查了 StackOverflow 并发现了这两个问题:

我使用 php 实现了我的推送系统:

    // Create the payload body
    $body['aps'] = [
        'alert' => $notification->getMessage(),//$notification is just a notification model, where getMessage() returns the message I want to send as string
        'sound' => 'default'
    ];

    // Encode the payload as JSON
    $payload = json_encode($body);

    $fp = self::createSocket();
    foreach($devices as $device) {
        $token = $device->getToken();
        $msg = chr(0) . pack('n', 32) . pack('H*', str_replace(' ', '', $token)) . pack('n', strlen($payload)) . $payload;
        if(!self::sendSSLMessage($fp, $msg)){
        //$msg is a parameter of the method, it's the message as string
            fclose($fp);
            $fp = self::createSocket();
        }else{
           //Here I log "n notification sent" every 100 notifications
        }
     }
     fclose($fp);

这里是createSocket() 方法:

private static function createSocket(){
    $ctx = stream_context_create();
    stream_context_set_option($ctx, 'ssl', 'local_cert', PUSH_IOS_CERTIFICAT_LOCATION);
    stream_context_set_option($ctx, 'ssl', 'passphrase', PUSH_IOS_PARAPHRASE);
    // Open a connection to the APNS server
    $fp = stream_socket_client(
        'ssl://gateway.push.apple.com:2195', $err,
        $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
    stream_set_blocking ($fp, 0);
    if (!$fp) {
        FileLog::log("Ios failed to connect: $err $errstr");
    }
    return $fp;
}

还有sendSSLMessage() 方法:

private static function sendSSLMessage($fp, $msg, $tries = 0){
        if($tries >= 10){
            return false;
        }

        return fwrite($fp, $msg, strlen($msg)) ? self::sendSSLMessage($fp, $msg, $tries++) : true;
    }

我没有收到来自苹果的任何错误消息,一切看起来都很好,只是没有人收到通知。

在此之前,我使用一种方法为每条消息创建一个套接字连接并在发送消息后关闭它,但它太慢了,所以我们决定更改它,所以我知道这不是与客户端相关的问题。

【问题讨论】:

    标签: php push-notification apple-push-notifications


    【解决方案1】:

    您必须先创建$fp 套接字,然后将其传递给sendSSLMessage

    // initally create Socket here
    $fp = self::createSocket();
    
    foreach($devices as $device) {
        $token = $device->getToken();
        $msg = chr(0) . pack('n', 32) . pack('H*', str_replace(' ', '', $token)) . pack('n', strlen($payload)) . $payload;
    
        if(!self::sendSSLMessage($fp, $msg)){
            fclose($fp);
            $fp = self::createSocket();
        }
    }
    fclose($fp);
    

    更新

    // define in $body['aps'] message with sub array like this
    $message = $notification->getMessage();
    $body['aps'] = array(
                'alert' => array(
                          'body' => $message,
                ),
                'sound' => 'default',
    );
    

    【讨论】:

    • 抱歉,我也忘记粘贴这个了,但我是在 foreach 循环之前完成的。我将编辑问题以添加这一行。
    • 好的,那么 PUSH_IOS_CERTIFICAT_LOCATION .pem 文件权限呢?重要的是它将具有正确的权限尝试将其更改为 0777
    • 完成了,我也看到没有 SSL 错误,因为如果我有 SSL 错误,它会添加到日志中(我删除了代码中的每个日志调用,但有很多)
    • 好的,我确实在我的答案中更新了一个关于消息发送部分的注释
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    相关资源
    最近更新 更多