37

Server Sent Events をリッスンする Web アプリケーションがあります。複数のウィンドウを開いた状態で作業およびテストを行っているときに、うまくいかず、間違った方向を向いて頭を何度も叩きました。最終的に、問題は同時接続にあることに気付きました。

ただし、私は非常に限られた数をテストしており、Apache でテストを実行している場合でも (ノードを使用する必要があることはわかっています)。

その後、ブラウザを切り替えたところ、非常に興味深いことに気付きました。明らかに、Chrome は Server Sent Events の接続を 4 ~ 5 に制限していますが、Opera はそうではありません。一方、Firefox は、4 ~ 5 回の同時接続の後、他のページの読み込みを拒否します

この背後にある理由は何ですか? この制限は、同じソースからの SSE 接続にのみ適用されますか? それとも、別のドメインから接続をテストして開いても同じでしょうか? SSE を誤用している可能性はありますか?これは実際にブラウザをブロックしていますか、またはこれは既知の動作ですか? それを回避する方法はありますか?

4

3 に答える 3

51

これがすべてのブラウザーで機能する方法は、各ドメインが取得する接続の量が制限されており、制限がアプリケーション全体に対してグローバルであることです。つまり、リアルタイム通信用に開いている接続が 1 つある場合、画像、CSS、およびその他のページをロードするための接続が 1 つ少なくなります。その上、新しいタブまたはウィンドウの新しい接続を取得しないため、それらはすべて同じ量の接続を共有する必要があります。これは非常にイライラさせられますが、接続を制限する十分な理由があります。数年前、この制限はすべてのブラウザで 2 でした (( http://www.ietf.org/rfc/rfc2616.txt ) HTTP1.1 仕様のルールに基づく) が、現在、ほとんどのブラウザは 4 ~ 10 の接続を使用しています。全般的。一方、モバイル ブラウザは、バッテリーを節約するために、接続の量を制限する必要があります。

これらのトリックが利用可能です:

  1. より多くのホスト名を使用してください。exを割り当てることによって。www1.domain.com、www2.domain.com は、ホスト名ごとに新しい接続を取得します。このトリックは、すべてのブラウザーで機能します。ドメイン全体を含むように Cookie ドメインを変更することを忘れないでください (www.domain.com ではなく domain.com)。
  2. Web ソケットを使用します。Web ソケットはこれらの制限によって制限されず、さらに重要なことに、他の Web サイト コンテンツと競合しません。
  3. 新しいタブ/ウィンドウを開くときに同じ接続を再利用します。すべてのリアルタイム通信ロジックをオブジェクト呼び出しハブに集めた場合、次のように、開いているすべてのウィンドウでそのオブジェクトを呼び出すことができます。

    window.hub = window.opener ? window.opener.hub || new Hub()

  4. またはフラッシュを使用してください - 最近では最善のアドバイスではありませんが、websocket がオプションでない場合でもオプションになる可能性があります。
  5. 新しい要求を開始する前にキューに入れられた要求をクリアできるように、各 SSE 要求の間に数秒の時間を追加することを忘れないでください。また、ユーザーが非アクティブである 1 秒ごとに待機時間を少し追加します。これにより、アクティブなユーザーにサーバー リソースを集中させることができます。また、 Thundering Herd Problemを回避するためにランダムな数の遅延を追加します

Java や C# などのマルチスレッドのブロッキング言語を使用する場合、アプリケーションの残りの部分に必要な長いポーリング リクエストでリソースを使用するリスクがあることを覚えておく必要があります。たとえば C# では、各リクエストは Session オブジェクトをロックします。つまり、SSE リクエストがアクティブな間、アプリケーション全体が応答しなくなります。

NodeJs は、すでに理解しているように、多くの理由でこれらのことに最適です。NodeJS を使用していた場合は、websockets、flashsockets、および XHR ポーリングを使用してこれらすべての問題を処理する socket.io または engine.io を使用していたでしょう。また、非ブロッキングでシングルスレッドであるため、送信を待機しているときにサーバー上のリソースをほとんど消費しません。AC# アプリケーションは、待機中の要求ごとに 1 つのスレッドを消費し、そのスレッドだけで少なくとも 2MB のメモリを消費します。

于 2014-02-26T10:26:55.887 に答える