9

一部のブラウザがHTTPポーリングを防止することを読みました(リクエストのレートを制限することで推測します)...

https://github.com/sstrigler/JSJaCから:

注:最近のほとんどのブラウザのセキュリティ制限により、HTTPポーリングを使用できなくなっているため、このモジュールはデフォルトで無効になっています。使用中にコンパイルしたい場合は、「ポーリングを行う」。

これは、私のJavaScriptのいくつかの誤動作を説明する可能性があります(実際に成功したとしても、リクエストが送信または再試行されない場合があります)。しかし、私は詳細についてのさらなる情報を見つけることができませんでした。

質問

  • 「x秒あたりの最大リクエスト数n」の場合、xとnの通常/デフォルト設定は何ですか?
  • これに適したリソースはありますか?
  • レート制限のためにリクエストが「遅延」または「拒否」されたかどうかを検出する方法はありますか?

ご協力いただきありがとうございます...

ステファン

4

6 に答える 6

4

はい、私が知る限り、デフォルトのプール制限は10で、デフォルトのリクエストタイムアウトはリクエストごとに30秒ですが、タイムアウトとポーリングの制限は制御でき、ブラウザごとに異なる制限が実装されています。

このGoogleの実装をチェックしてください。

これは、タイムアウトエラーをキャッチする素晴らしい実装です!

Firefoxの詳細はここにあります!

Internet Explorerの詳細は、Windowsレジストリ内から制御されます。

この質問もご覧ください。

基本的に、制御する方法は、ブラウザーの制限を変更することではなく、それらを順守することです。したがって、スロットルと呼ばれる手法を適用します。

関数のFIFO/優先キューを作成することと考えてください。xhrリクエストをメンバーとして受け取り、それらの間の遅延を強制するキュー構造体はXhrPollです。たとえば、私はJsonpを使用して、別のドメインにあるnode.jsサーバーからデータを取得していますが、もちろんブラウザーの制限のためにポーリングしています。それ以外の場合、サーバーからの応答はゼロになります。これは、ブラウザーの制限によるものです。

私は実際に送信されることになっているすべてのリクエストに対してコンソールログを作成していますが、すべてがログに記録されているわけではありません。したがって、ブラウザはそれらを制限します。

私はあなたを助けることでさらに具体的になります。私のウェブサイトには、数十または数百の記事のビューを表示することになっているページがあります。あなたはクールな水平スライダーを使用してそれらを通過します。

スライダーの現在の値は、現在の「ページ」と一致します。1ページに5つの記事しか表示しておらず、パフォーマンスに深刻な影響を与えずに何千もの記事を「オンロード」で正確にロードすることはできないため、現在のページの記事をロードします。クロスドメインリクエストをPythonスクリプトに送信することで、MongoDBからそれらを取得します。

スクリプトは、「ページ」のDOM要素を構築するために必要なすべての詳細を含む5つのオブジェクトの配列を返すことになっています。ただし、いくつかの問題があります。

まず、スライダーは多かれ少なかれ値の変化であるため、非常に高速に動作します。ドラッグドロップ機能、キーダウンイベントなどがある場合でも、実際の変更にはミリ秒かかります。ただし、スライダーのコードは次のようになります。

goog.events.listen(slider, goog.events.EventType.CHANGE, function() {
    myProject.Articles.page(slider.getValue());
}

Slider.getValue()メソッドは、現在のページ番号を含むintを返すため、基本的に次の場所からロードする必要があります。

currentPage * articlesPerPage to (currentPage * articlesPerPage + 1) - 1

しかし、ロードするために、私は次のようなことをします:私はストレージエンジンを持っています(それを配列と考えてください):

  • コンテンツがまだないか確認します
  • そうである場合は、別のリクエストを行う意味がないため、作成済みのDOM要素を配置した配列からDOM要素を取得してください。
  • そうでない場合は、取得する必要があるため、言及したリクエストを送信する必要があります。これは、(ブラウザーの制限を考慮せずに)次のようになります。

    JSONP.send({'action':'getMeSomeArticles'、'start':start、'length':itemsPerPage、function(callback){

    //コールバックをすばやく解析して、一貫性があることを確認します// DOM要素を作成し、//クライアント側のストレージにデータを入力して//ユーザーのビューを更新します。}}

問題は、そのスライダーを変更できる速度にあります。すべての変更がリクエストをトリガーすると思われるため(通常のXhrリクエストでも同じことが起こります)、基本的にすべてのブラウザーの制限を超えています。したがって、スロットルがなければ、ほとんどのリクエストに対して「コールバック」はありません。「コールバック」は、JSONPリクエストによって返されるJSコードです(これは、他の何よりもリモートスクリプトの包含です)。

つまり、私が行うことは、POLLではなく優先キューにリクエストをプッシュすることです。これで、複数のリクエストを同時に送信する必要がなくなりました。キューが空の場合、最近追加されたメンバーが実行され、全員が満足します。そうでない場合は、進行中の未完了のリクエストがすべてキャンセルされ、最後のリクエストのみが実行されます。

ここで、私の特定のケースでは、バイナリ検索(0(log n))を実行して、ストレージエンジンに前の要求のデータがまだないかどうかを確認します。これにより、前の要求が完了したかどうかがわかります。ある場合はキューから削除され、現在のキューが処理されます。そうでない場合は、新しいキューが起動します。などなど。

繰り返しになりますが、速度を考慮し、Internet Explorerなどのブラウザを使いたい場合は、上記の手順を約3〜4ステップ先に実行します。したがって、すべてがクライアント側のストレージエンジンになるまで、20ページ先にプリロードします。このようにして、すべての制限が正常に処理されます。

クールダウン時間は、20ページをスライドするのにかかる最小時間でカバーされ、スロットルは、常に1つ以下のアクティブな要求があることを確認します(Internet Explorer 5までの下位互換性があります)。

私がこれをすべて書いた理由は、FIFO構造から直接遅延を強制できるとは限らないという例を示すためです。これは、呼び出しがユーザーに表示されるものに変わる必要があり、正確に作成したくないためです。ユーザーは、1つのページがレンダリングされるまで10〜15秒待ちます。

また、常にポーリングとポーリングの必要性を最小限に抑えます(すべてのブラウザーが実際にそれらを使用して良いことを行うわけではないため、同時に発生するAjaxイベント)。たとえば、コンテンツを取得するために1つのリクエストを送信し、アプリの指標で表示されるようにそのコンテンツを追跡するために別のリクエストを送信するようなことを行う代わりに、サーバーレベルで可能な限り多くのタスクを実行します。

もちろん、おそらくエラーを適切に追跡したいので、選択したライブラリのXhrオブジェクトはajaxのエラー処理を実装します。あなたは素晴らしい開発者なので、それらを利用したいと考えています。

したがって、try-catchブロックが適切に配置されているとします。シナリオは次のとおりです。Ajax呼び出しが終了し、JSONを返すことになっていますが、呼び出しが何らかの理由で失敗しました。ただし、JSONを解析して、必要な処理を実行しようとします。それで

function onAjaxSuccess (ajaxResponse) {
    try {
        var yourObj = JSON.parse(ajaxRespose);
    } catch (err) {
    // Now I've actually seen this on a number of occasions, to log that an error occur
    // a lot of developers will attempt to send yet another ajax request to log the
    // failure of the previous one.
    // for these reasons, workers exist.
    myProject.worker.message('preferrably a pre-determined error code should go here');
    // Then only the worker should again throttle and poll the ajax requests that log the
    //specific error. 
};

};

ブラウザーの制限に遭遇するまで、可能な限り多くのXhrリクエストを同時に起動しようとするさまざまな実装を見てきましたが、ブラウザーのクールダウンを待って起動されなかったリクエストを停止するのに非常に優れています。 '、私があなたにアドバイスできることは、次のことについて考えることです:

  • アプリの速度はどれほど重要ですか?
  • I / Oはどれだけスケーラブルでどれほど集中的になりますか?

前者の答えが「非常に」で、後者の「OMFGモダンテクノロジー」の答えである場合は、コードとアーキテクチャを可能な限り最適化して、10個の同時Xhrリクエストを送信する必要がないようにしてください。また、大規模なアプリの場合は、プロセスをマルチスレッド化します。これを実現するJavaScriptの方法は、ワーカーを使用することです。または、ECMAボードを呼び出して、これをデフォルトにするように指示し、ここに投稿して、残りのJS開発者がJSでネイティブマルチスレッドを楽しむことができるようにすることもできます:)(dafuqはこれについてどう思いませんでしたか?! ?!)

于 2012-10-16T19:41:48.763 に答える
3

ステファン、以下の簡単な答え:

-「x秒あたりの最大リクエスト数n」の場合、xとnの通常/デフォルト設定は何ですか?これは、サーバーの制限のように聞こえます。ブラウザのものは通常次のように聞こえます:-「同じホスト名の最大リクエスト数はxです」-「任意のホスト名の最大接続数はyです」

-これに適したリソースはありますか? http://www.browserscope.org/?category=network(テーブルヘッダーにカーソルを合わせて、測定値を確認します) http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-接続

-レート制限のためにリクエストが「遅延」または「拒否」されたかどうかを検出する方法はありますか?「Connection:close」のhttpヘッダーを調べてサーバーの制限を検出することもできますが、JavaScriptで、ブラウザーに依存しない一貫した方法で非常に多くのブラウザーから設定を読み取ることができるかどうかはわかりません。(Firefoxの場合、このhttp://support.mozilla.org/en-US/questions/746848を読むことができます)

この簡単な答えがお役に立てば幸いです。

于 2012-10-18T10:28:26.897 に答える
2

いいえ、ブラウザはポーリングに影響を与えません。そのページで意味されていたのは同一生成元ポリシーだと思います。元のページと同じホストとポートにしかアクセスできません。

接続自体に対する唯一の既知の制限は、通常、同じホストへの同時接続は2〜4つしかないことです。

于 2012-10-15T02:44:32.620 に答える
2

長いポーリングを使用するアプリ、独自のWebサーバーを使用するC ++バックエンドを使用するアプリ、Apache2を使用するPHPバックエンドを使用するアプリを作成しました。

私の長いポーリングタイムアウトは4..10秒です。何かが発生したとき、または4..10秒が経過すると、サーバーは空の応答を返します。次に、クライアントはすぐに別のAJAXリクエストを開始します。以前のAJAXハンドラーからAJAX呼び出しを開始すると一部のブラウザーがハングアップすることがわかったため、次のAJAX要求を開始するために小さな値でsetTimeout()を使用しています。

サーバーに送信する必要があるクライアント側で何かが発生した場合、別のAJAX要求を使用しますが、これは一方向の問題です。サーバーは応答を送信せず、クライアントは何も処理しません。操作の結果(ある場合)は、ロングポーリングで受信されます。最大が必要です。2すべてのブラウザがサポートするサーバーへの接続。

クライアントが500の場合、サーバー側のWebサーバースレッドが500を意味し、一緒に移動して負荷のピークが発生することに注意してください。何かが発生すると、サーバーはクライアントごとに同時にレポートする必要があるため、クライアントはほぼ同じ時間で処理すると、次の長いリクエストが同時に開始され、それ以降、タイムアウトも同時に期限切れになり、次のリクエストも期限切れになります。rndタイムアウト、たとえば4 rnd(0..4)でトリックすることはできますが、何かが起こった場合、それらは再び「同期」し、報告可能な何かが発生したときにすべてのリクエストを同時に処理する必要があります。

私はルーターを通してそれをテストしました、そしてそれは働きます。私は、ルーターが4..10の遅れを尊重していると思います。それは、ルーターがキャンセルすべきだとは考えていない、遅いwebapge(遠く、遠く)の速度のあたりです。

私のPHPの作業は共同スプレッドシートです。Enterキーを押すと、いくつかのブラウザーで同時に更新されているので、見栄えがします。楽しむ!

于 2012-10-17T15:32:47.807 に答える
1

ajaxリクエストの数に制限はありません。ただし、同じホストとポートにあります。

サーバーは、その設定に基づいて、マシンからの要求を制限できません。

例えば。サーバーは、指定された時間内に同じマシンからの要求が少ない場合、要求を拒否するように設定できます。

于 2012-10-18T05:33:06.820 に答える
0

javascriptコードの小さな間違いの後、2つのajaxリクエストを呼び出す各ステップで終わりのないループが発生しました。firebugでは、firefoxが遅くなり始め、応答せず、最終的にクラッシュするまで、ますます多くのリクエストを見ることができました。

だから、はい、「限界」があります;)

于 2012-10-18T09:28:25.953 に答える