APNS拡張ペイロードでエラーレスポンスを取得
- 通知期限
- エラー応答
をサポート。
単純形式に以下を変更、追加して通知パケットを送信
- 1(固定コマンド 1btyte)
- 応答識別子(integer 4byte)
- 有効期限(UNIXタイムスタンプ integer 4byte)
拡張ペイロードサンプル
実際の通知payload生成は以下のような感じ。
function get_payload($token_id, $data, $respose ) { //token_idを16進→バイナリへ $deviceToken = pack('H64',$token_id); //エラー時はこの$resposeに対してエラーがあったと応答 $responce_id = pack('N', $respose ); //メッセージ保存は1週間 $timeout = pack('N', time()+(7 * 24 * 60 * 60) ); //JSON文字列作成 $payload = '{ "aps" :{ "badge" : '. $data.' } }'; //バイナリデータ作成 $msg = pack('C','1'). $responce_id.$timeout. pack('n',32). //Token length $deviceToken. //device Token(binary) pack('n',strlen($payload)) . //Payload length $payload; return($msg); }
エラーパケットの読み込みは、エラー時のみ応答パケットを返却するので、
正常時にreadしようとすると、ストリームがデータを読み出せる状態になるまで待ちつづけてしまう。
なので、ストリームを非ブロックモードに指定。
//APNSサーバ接続 $ctx = stream_context_create(); stream_context_set_option( $ctx, 'ssl', 'local_cert', $cert_file ); stream_context_set_option( $ctx, 'ssl', 'verify_peer', TRUE ); $fp = stream_socket_client( $url, $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx ); //非ブロックモードに stream_set_blocking( $fp, 0 ); //ペイロード生成 $this->get_payload( $token_id, $data, $member_id ); //パケット送信 for ($written = 0; $written < strlen($payload); $written += $fwrite) { $fwrite = fwrite($fp, substr($payload, $written)); if (!$fwrite) { $this->_log_err( 'fwrite error ['.$written.']' ); break; } } //エラーキャッチ $error_byte = @fread( $fp, 6 ); if( strlen( $error_byte ) == 6 ) { error_log( var_export( unpack( "C", substr( $error_byte, 1, 1 ) ), 1) ); error_log( var_export( unpack( "N", substr( $error_byte, 2 ) ), 1) ); }
これで、APNSのエラーがフックできる。
応答パケットについてはDocumentを読むのが早いがメモついでに。
command (1byte 固定値:8)
status (1byte
0:遭遇エラーなし,
1:処理エラー,
2:トークン欠如,
3:トピック欠如,
4:ペイロード欠如,
5:無効トークンサイズ,
6:無効トピックサイズ,
7:無効ペイロードサイズ,
8:無効トークン,
255:不明
)
identifer (4byte ペイロード指定の識別子($responseの値))