1

プッシュ メッセージの送信には、変更されたバージョンのeasy-apnsを使用しています。強化されたプッシュ メッセージ形式では、Apple サーバーはエラーが発生した場合に応答し、すべてがうまくいっている場合は何もしません。

問題は、各メッセージが送信された後、エラーが発生するまで一定時間待たなければならないことです。たとえば、1 秒経っても応答がない場合は、すべて問題がなかったと見なされます。

20000 件のプッシュ メッセージがあるため、これには非常に時間がかかります。より高速な方法でエラーをリッスンする方法はありますか? たとえば、1000 台のデバイスに送信してからエラーをリッスンしますか? 接続が閉じられた場合はどうなりますか? エラー応答を読み取ることはできますか?

理想的には、ある種の非同期の書き込みと読み取りですが、それは不可能だと思います。

対応するコードは次のとおりです。

    $fp = $this->connect();

    $expiry = time()+60*60;

    // construct message
    $msg = chr(1).pack("N",$batchid).pack("N",$expiry).pack("n",32).pack('H*',$devicetoken).pack("n",strlen($payload)).$payload;

    // send message to Apple
    $fwrite = fwrite($fp, $msg);

    if(!$fwrite) {
        // connection has been closed
        $this->disconnect();
        throw new Exception("Connection closed");

    } else {
        // read response from Apple

        // Timeout. 1 million micro seconds = 1 second
        $tv_sec = 1;
        $tv_usec = 0;

        $r = array($fp);
        $we = null; // Temporaries. "Only variables can be passed as reference."

        // PROBLEM: this method waits for $tv_sec seconds for a response
        $numChanged = stream_select($r, $we, $we, $tv_sec, $tv_usec);

        if( $numChanged === false ) {
            throw new Exception("Failed selecting stream to read.");
        } elseif ( $numChanged > 0 ) {

            $command = ord( fread($fp, 1) );
            $status = ord( fread($fp, 1) );
            $identifier = implode('', unpack("N", fread($fp, 4)));

            if( $status > 0 ) {

                // The socket has also been closed. Cause reopening in the loop outside.
                $this->disconnect();
                throw new MessageException("APNS responded with status $status: {$this->statusDesc[$status]} ($devicetoken).".microtime(), $status);

            } else {
                // unknown response, assume ok
            }

        } else {
            // no response, assume ok
        }
    }
4

0 に答える 0