16

マシンに過負荷をかける前に、セットアップできる同時 SSE (別名 EventSource) 接続の数を確認したかったのです。しかし、Firefox (Firefox 18 または Firefox 20) でテストしたところ、6 つの接続で停止しました。追加の接続ではエラーは発生しませんが、データは送信されません。(Firebug では、接続を待っている状態で表示されます。) Chromium 25 も 6 接続で停止し、Opera 12.15 も同様でした。しかし、サーバー側の制限ではないようです (私は Apache + PHP を使用しています)。3 つのブラウザーすべてを同時に実行でき (つまり、18 接続)、すべてが同じ IP アドレスから来ているためです。(サーバーとクライアントは同じマシン上にありますが、127.0.0.1 ではなく 172.16.xx アドレスを使用しています。)

そこで、CORS でテストをセットアップし、グローバル IP を持つ別のサーバーに接続してみました。今回は Firefox で 12 個の接続を取得しました。結局、それはApacheの構成であると示唆していますか? いいえ、Opera はまだ 6 つの接続しか取得できません。(CORS が機能していないように見えるため、Chrome の番号はありません。) また、両方のサーバーに接続して、Firefox で合計 18 の接続 (ただし、それ以上の接続はありません)、Opera で合計 12 の接続を実行することもできました。

3 番目のテストとして、バックエンドと html の両方をリモート サーバーに移動し、そのようにページをロードしました。今回は Firefox の接続数が 10 の制限に達しました!?! Opera にはまだ 6 の制限があります。また、Chromium (今回は CORS が関与していないため動作します) には 6 の制限があります。

この 6 という数字がどこから来たのか、また 3 つのブラウザがすべて同じであるというのが単なる偶然であるとしたら、何か洞察をいただければ幸いです。特に、Firefox が 6 の場合もあれば、10 の場合もある、12 の場合もある理由についての洞察 ( SSE 仕様では、接続の最大数が定義されていないようです)。


Apache の設定では prefork を使用します。つまり、次の設定を意味します。

StartServers          5
MinSpareServers       5
MaxSpareServers      10
MaxClients          150
MaxRequestsPerChild   0

(ローカル (Ubuntu 10.04) サーバーとグローバル (Ubuntu 11.10) サーバーの両方で、ここでは同一の Apache 設定が使用されています。) キーとなる数字は、MaxClients が 150 であることだと思います。StartServers を 5 ではなく 50 に変更して簡単な実験を行いましたが、結果は同じでした。結果。


クライアント側の HTML/javascript は次のとおりです (別のサーバーへの接続を実験する場合は、1 行または 2 行のコメントを外して変更します。ここに示すように、HTML と同じディレクトリに sse.php が見つかると想定しています)。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>SSE Stresstest</title>
</head>
<body>
<p id="err"></p>
<p id="x"></p>
<script>
function start(){

function onMessage(e){
document.getElementById('x').innerHTML+=e.origin+":"+this.dummy_n+":"+e.data+"<br/>";
};

function onError(e){
document.getElementById('err').innerHTML+="ERR:"+this.dummy_n+":"+JSON.stringify(e)+"<br/>";
};

for(var n=1;n<=32;++n){
    //NB. 't' primarily to avoid caching
    var url='sse.php?dummy_n='+n+'&t='+(new Date().getTime());
    //if(n%2==0)
    //    url='http://example.com/sse.php?dummy_n='+n+'&t='+(new Date().getTime());
    var es=new EventSource(url);
    es.dummy_n=n;   //So we can identify each one
    es.addEventListener('error',onError,false);
    es.addEventListener('message',onMessage,false);
    }
}

setTimeout("start()",1000);   //Only Safari needs the 1000ms delay.
</script>
</body>
</html>

バックエンドの sse.php スクリプトは次のようになります。

<?php
$ip=array_key_exists('SERVER_ADDR',$_SERVER)?$_SERVER['SERVER_ADDR']:'cli';
header('Content-Type: text/event-stream');
header('Access-Control-Allow-Origin: *');   //CORS: allow access from anywhere
@ob_flush();@flush();
//Now the main loop
while(true){
    echo "data:".gmdate("Y-m-d H:i:s,").$ip."\n\n";
    @ob_flush();@flush();
    sleep(1);
    }
?>
4

3 に答える 3

17

その理由は、すべての EventSource オブジェクトが新しい HTTP セッションを開始し、実際に新しい tcp/ip ソケットを開くためである可能性があります。サーバーから無限ループで継続的にデータをプッシュしているため、ソケットは継続的に開いたままになります。すべての Web ブラウザーには、同じサーバーへの同時アクティブな HTTP/1 接続の上限があります。通常、RFC 2616 に従って 4 から 6 の範囲です。ブラウザは、この制限を超えると、新しい接続を開くことを妨げています。

HTTP/2 および HTTP/3 では、制限が高くなります (既定では 100 接続)。

ここでもいくつかの詳細情報を学ぶことができます:
http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/

于 2013-05-31T08:40:40.353 に答える
4

ホスト名列ごとの接続を参照してください: http://www.browserscope.org/?category=network&v=1

誰もが望むよりも多くの情報があり、観察された「6」が基本的に単なる慣例であることを示しています。

RFC2616は 2 の制限を提案していますが、誰もがそれを無視しています。したがって、http://trac.tools.ietf.org/wg/httpbis/trac/ticket/131はその提案を削除します。

カスタマイズ

IEはレジストリから設定できるようです。

Firefox は about:config 内から構成できnetwork.http、さまざまな設定をフィルターします。network.http.max-persistent-connections-per-server変える方です。

現在、 Chromeを構成できません

Opera はabout:config、[パフォーマンス] を開いて [最大永続接続サーバー] を変更することで構成できます。

サファリ?いいえ、明らかに設定できません。

于 2013-05-31T11:05:06.467 に答える
0

これを参照https://developer.mozilla.org/en-US/docs/Web/API/EventSource

Firefox と Chrome は、ブラウザー + ドメインによって開かれる接続の数に制限を設定すると述べられています。

HTTP/2 で使用しない場合、SSE は開く接続の最大数に制限があります。これは、制限がブラウザーごとにあり、非常に低い数 (6) に設定されているため、さまざまなタブを開くときに特に苦痛になる可能性があります。この問題は、Chrome と Firefox では「修正されません」とマークされています。この制限はブラウザー + ドメインごとにあるため、すべてのタブで www.example1.com への 6 つの SSE 接続と、www.example2.com への別の 6 つの SSE 接続を開くことができることを意味します。(スタックオーバーフローから)。HTTP/2 を使用する場合、同時 HTTP ストリームの最大数はサーバーとクライアントの間でネゴシエートされます (デフォルトは 100)。

于 2020-06-17T11:33:29.033 に答える