私は、Androidを使用するクライアント側(具体的にはモバイル)アプリケーションでのみ作業しました。すべてのネットワークは、HttpUrlConnectionなどのフレームワークが提供するコンポーネントを使用してHTTPレイヤーで処理されます。
しかし、Websockets/XMPPなどのプッシュメッセージングシステムはすべて、サーバーへの永続的な接続を維持します。 Google Play対応デバイスに組み込まれたGoogleのGCMでさえ、サーバーへの永続的な接続を維持します。
私の質問は、これはバッテリーを消耗させずにどのように機能するのですか?連続的なHTTPリクエストを連続して行うと、バッテリーの消耗が大きくなります。同じ問題が発生することなく、これらの永続的な接続はどのように維持されますか?
開いているTCP接続は論理的な状態です。そのデータが常にやり取りされているという意味ではありません。最初の ウェイハンドシェイク の後、「接続済み」状態に入りました。 3方向切断が発生するか、キープアライブが失敗するまで、その状態にあります。
接続の存続期間中に、基礎となる「物理」メディアからのリソースを確立して、その接続のデータ転送を行うことができます。有線接続の場合、これはイーサネットフレームを転送する問題です。 3G/4Gワイヤレス接続の場合、これは必要に応じて下位レベルのプロトコルとの接続を確立することによって行われます。
したがって、接続の存続期間中、物理的な基礎となるデータ接続は存在しません。代わりに、TCP接続のいずれかのピアがデータを送信する必要があるのを待機しています。
もう1つの問題は、TCPがackベースであることです。 TCPピアは、確実に受信されたものを互いに効率的に通知し合うことができます。失敗すると、TCPが再送信されます。これは、かなり信頼できる物理リンクに最適ですが、ワイヤレス接続のように非常にノイズの多い/壊れたリンクではばらばらになる傾向があります。ご想像のとおり、これらの環境では確認応答/再送信が非常に頻繁に発生します。
したがって、通常、基盤となるワイヤレスプロトコルは、TCP再送信の必要性を減らすためにできる限りのことを行います。たとえば、ワイヤレスレイヤーには多くのエラーチェックが組み込まれています。ワイヤレスレルム(基地局/電話)のピアもnakベースのプロトコルを使用して、相手何も受信しませんでした。 nakベースであることにより、エラーをチェックする際のオーバーヘッドが削減されます(反対側がそれを言わない限り、すべてが正常であると想定されます)。また、エラーbeforeに対処し、TCPレイヤーにバブルアップすることで、大量のTCPを回避できます。再送信を試みるスラッシング。さらに、ワイヤレスピアへの再送信の範囲が減少します。電話は、インターネット上のどこかにあるサーバーに再度パケットを要求する必要はありません。ワイヤレスリンク上の基地局だけです。