1

私はJavaでのAppleプッシュ通知のサーバー側開発を研究しています。失敗したメッセージを検出し、不良メッセージに続くメッセージを再送信するために、拡張フォーマットを使用しています。Appleがプッシュ通知の配信を保証しないことは知っていますが、Appleが私のメッセージを受信したかどうか、およびエラーが含まれていたかどうかを知りたいです。

無効なメッセージ(無効なデバイストークン、大きすぎるペイロードなど)をAppleに送信しようとすると、ソケットが閉じられる前にさらにいくつかのメッセージを送信できることに気付きました。ソケットが閉じていると、Appleからエラーコードを読み取るには遅すぎるので、どのメッセージが悪いメッセージであったかわかりません(または、悪いメッセージがあったとしても、Appleは、接続がない場合でも接続が時々閉じる可能性があると言っているので)エラー)。

これを処理するためにJavaPNのソースで見たアプローチは、各メッセージ(またはメッセージのグループ)が送信された直後にAppleからの応答を読み取ることです。頻繁に実行される場合はソケットからの読み取り。読み取るものがない場合はタイムアウトを待機します。これは、プッシュ通知を頻繁に送信しない場合は許容されます。

多数の通知を高頻度(たとえば1秒あたり数百)で送信しようとすると、各メッセージの後で停止してAppleからの応答を待つことはできません(応答を20ミリ秒だけ待っても、それは1秒あたりのメッセージ数を50に制限すると、Appleがエラー応答を書き込むのにかかる時間を知る方法がないため、短時間待つだけでは不十分な場合があります)。各メッセージの後に起こりうるエラーを読むのをやめないと、Appleへのメッセージの送信中に接続が閉じられるリスクがあります。その場合、接続を閉じる原因となったメッセージのIDを取得できません。 。

私が検討しているもう1つのアプローチは、読み取りと書き込みを別々のスレッドで実行することです。このようにして、Appleにメッセージを送信する速度を損なうことなく、(接続が閉じられる前に)Appleからエラーメッセージを受け取る可能性がはるかに高くなります。このアプローチはプログラム的にはより複雑であり、私のサーバーはAPNを複数のiOSアプリケーションに送信することが期待されており、それぞれが独自のソケットとリーダー/ライタースレッドを必要とするため、必要なスレッドの数が2倍になります。

上記のAPNサーバーの動作はすべて、Appleのサンドボックスサーバーにプッシュ通知を送信しようとしたときに学習されました。Appleの本番サーバーの動作が優れているかどうかはわかりません。また、本番サーバーでテストを実行することをお勧めするかどうかもわかりません。

私の質問-パフォーマンスを犠牲にすることなく、接続を閉じる前にAlphaからのエラー応答を確実に読み取る方法はありますか?サーバーによって閉じられた後、どういうわけかソケットから入力を読み取ることは可能ですか?

4

1 に答える 1

0

私はあなたと同じ問題に遭遇しました。そして、私は2つのアプローチを試しましたが、いずれも接続を閉じる前にAppleからのエラー応答を確実に読み取ることができません:

  1. ソケットごとに 2 つのスレッドを開始しました。1 つは連続書き込み用、もう 1 つは読み取りブロック用です。ほとんどの場合、読み取りスレッドは、書き込みで「Socket Broken」例外が発生したときにエラー応答を読み取ることができますが、完全に信頼できるわけではありません。
  2. socket ごとに、1 つのスレッドのみを開始して継続的に書き込み、例外が発生した場合は、try キャッシュ ブロックでエラー応答の読み取りを試みました。ほとんどの場合、ソケットは閉じられているため、例外だけを読み取ります。
于 2013-06-17T02:58:18.997 に答える