web-dev-qa-db-ja.com

Googleドライブはリアルタイムの更新を取得するためにどのテクノロジーを使用していますか?

Googleドライブはリアルタイムでどのテクノロジーを使用していますか?

複数のユーザーがアクセスしているGoogleドライブドキュメントを入力すると、Chrome Developer Tools Networkタブに、WebSocketがないことが表示されます。

AJAX呼び出しの2つの最も頻繁なタイプには、URLに「bind?」または「save?」のいずれかが含まれています。「save?」POSTリクエスト入力するたびに作成されます。これは、サーバーに更新を送信するための通常のAJAXです。

別のユーザーが入力すると、最新の「バインド?」 GET呼び出しは開いたままで、その接続を介して転送されるデータの量は増加します。定期的に「バインド?」は閉じられ、新しいものが開かれ、ロジックは期間とデータサイズの関数のようです。

サーバーが更新を送信すると応答が完了しないため、これはロングポーリングではありません。

Content-typeが「text/stream」ではなく「text/plain」であるため、これはサーバー送信イベントではないようです。

Googleがやっていることに名前はありますか?もしそうなら、これをどのように実装してみることができますか?

Chrome Dev Tools - editing a Google Drive document

37
Max Heiber

ドライブのリアルタイム更新のためのGoogleのソリューションに名前はありますか(「ロングポーリング」や「ソケット」など)?

今まで名前はありませんでした。ポーリングやロングポーリングとは対照的に、これを「ポーリングなし」と呼びます。

ポーリングでは、クライアントは定期的に新しいデータのクエリを送信します。

ロングポーリングを使用すると、クライアントはデータを照会し、サーバーは要求を保持して、更新がある場合は更新で応答を終了します。

ポーリングなし(Googleドライブが行うこと)は、リクエストが完了する前にブラウザーがリクエストの本文からデータを読み取る方法を利用します。そのため、共同編集者がより多くの入力と編集を行うと、サーバーは現在のリクエストにより多くのデータを追加します。特定の制限(コンテンツの長さまたは要求の期間)が満たされた場合、要求は完了し、クライアントはサーバーで新しい要求を開始します。

これを実装するにはどうすればよいですか?

クライアントがサーバーに更新を送信する場合:これは通常のPOSTで実行できます。

クライアントがサーバーからの更新をサブスクライブする場合:

  • クライアントは、更新ストリームのGETを送信し、応答が完了する前に応答の本文の読み取りを開始します。

    XHRオブジェクトは、リクエストが完了する前に progress イベントを発行できます。 (部分的な)応答には、xhr.responseTextを使用してアクセスできます。 ~~ fetchを使用して進行状況を監視する簡単な方法はありません まだ (2016年5月現在)~~ fetchを使用すると、次の方法で進行状況を監視できます- res.body ReadableStreamを使用

  • クライアントは、現在の要求が終了したときに新しい要求を開始する必要があります。

サーバーは:

  • どのクライアントがどの更新ストリームにサブスクライブしているかを追跡します。
  • 特定の更新ストリームのリクエストが来たら、レスポンスにデータを書き込みますが、データ量が大きくなるか、タイムアウトになるまでレスポンスを完了しないでください。

私の意見では、非ポーリングはロングポーリングよりも優れているように見えますが、あまり使用していません。ロングポーリングは、レイテンシとメッセージサイズの間のトレードオフを強制します(一定の更新レートが与えられた場合)、トレードオフのポーリングなしで行う必要はありません。ロングポーリングのもう1つの欠点は、多くのHTTPリクエストが発生し、毎回HTTPのオーバーヘッドが発生する可能性があることです。

ポーリングなしのWebSocketに対する大きな利点は、すべてのブラウザーでポーリングなしがサポートされていることですが、WebSocketのサポートはかなり優れています— IE10 +

48
Max Heiber