1

私はasyncsocketを使用してWindows.netサーバーへのクライアントとしてcocoaasyncsocketを使用してきました。ProtocolBuffersを使用してメッセージをエンコードしています。一緒に、これらは素晴らしいツールのセットを作ります。

ただし、最近、クライアントをサーバーに接続したままにしておくと、データを要求しようとすると、メッセージは送信されたように見えますが、サーバーに到達しないことに気付きました。ネットワークに問題があった場合のような通常の切断を受信して​​いないため、これを「サイレント」切断と呼んでいます。

デバッグするために次のメソッドを処理していますが、いずれも呼び出されません。

- (NSTimeInterval)onSocket:(AsyncSocket *)sock
  shouldTimeoutReadWithTag:(long)tag
                   elapsed:(NSTimeInterval)elapsed
                 bytesDone:(CFIndex)length {

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err

- (void)onSocketDidDisconnect:(AsyncSocket *)sock

何の通知もなく、私はこれをデバッグするのが難しいと感じています。同様に、サーバーは切断を表示しません。

誰かがこれをさらに分析する方法に私を向けることができますか?

どうもありがとう。

4

1 に答える 1

3

クライアントとサーバーが接続されていることを知りたい場合は、ハートビートまたは「キープアライブ」、つまり基本的に「Areyouthere」/「yes」と交換されるアプリケーションレベルのメッセージが必要です。

多くのルーターがアイドル状態のTCP接続をサイレントにドロップするため、これは特に最近の状況に当てはまります。それはTCPが設計された目的ではありませんが、それは現実です。

TCPには、接続層のハートビートを送信するか、SO_KEEPALIVEでキープアライブを送信するかを選択できますが、これが適切かどうかについては歴史的に議論がありました。設計者は、一時的な中間ネットワークの問題のためにソケットをドロップするのは間違っていると感じました。その期間中に実際にデータが送信されなかった場合、接続を切断する理由はありませんでした。他の人は、接続が良好であるかどうかを知ること自体が重要であると感じました。データを期待していたのにデータが届かなかった場合はどうなりますか?知りたくないですか?

最終的には、アプリケーションによって異なります。「新しい情報なし」がアプリケーションにとって重要な事実の主張である場合(たとえば、ニュースフィード、販売注文、市場データの価格変更)、「新しい情報なし」が実際の「新しい情報なし」であることを確認する必要があります。 「接続がサイレントに切断された」ではありません。それは明示的なメッセージを意味します。

では、どのくらいの頻度で送信する必要がありますか?

それは物事のバランスに依存します。1a)通常どのくらいの頻度でアップデートを入手しますか?1b)許容できる/通常の遅延(たとえば、これがプロセスの一部である場合、他のステップには通常数時間かかり、その後5〜10分が許容される場合があります)。2a)バッテリーと2b)ハートビートによるデータ使用量。バッテリー/電力への影響は重要だと思いますが、これらすべてを注意深く調べ、バランスをとる必要があります。

結局のところ、いつでもカバレッジを失う可能性があります(トンネルなど)。平均更新間隔の0.5〜5倍の間に更新がない場合にのみ、ハートビートを実行します。したがって、1分あたり2回の更新が予想される場合は、15秒から3分間アイドル状態のときにハートビートを実行し、何が最適かを判断します。ユーザーがアプリを「ライブ」で使用し、完了したら「オフ」にしている場合、とにかく使用しているため、バッテリーの寿命はそれほど問題にはなりません。更新を処理するためにデバイスをスリープ解除する場合、バッテリーの寿命は本当に問題です。

于 2011-03-17T11:36:56.837 に答える