16

我想看看在我的机器超载之前我可以同时设置多少个 SSE(又名 EventSource)连接。但是用 Firefox(Firefox 18 或 Firefox 20)测试它在 6 个连接处停止:额外的连接没有错误,但不发送任何数据。(在 Firebug 中,我可以看到它们在那里等待连接。) Chromium 25 也停止在 6 个连接处,Opera 12.15 也是如此。但这似乎不是服务器端的限制(我使用的是 Apache + PHP),因为我可以同时运行所有三个浏览器(即 18 个连接),并且都来自同一个 IP 地址。(服务器和客户端在同一台机器上,但使用 172.16.xx 地址,而不是 127.0.0.1。)

因此,我使用 CORS 设置了测试,并尝试连接到具有全球 IP 的另一台服务器。这次我获得了 12 个 Firefox 连接。暗示它毕竟是 Apache 配置?不,Opera 仍然只有 6 个连接。(Chrome 没有数字,因为 CORS 似乎不起作用。)我还可以运行连接到两台服务器,在 Firefox 中总共有 18 个连接(但不再有),在 Opera 中总共有 12 个。

作为第三次测试,我将后端和 html 都移动到了远程服务器,并以这种方式加载了页面。这次我达到了 Firefox 的 10 个连接的限制!?!Opera 仍然有 6 个限制。Chromium(因为这次没有涉及 CORS)有 6 个限制。

我希望能深入了解这个数字 6 的来源,以及所有三个浏览器都相同是否只是巧合。尤其是对为什么 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 更改为 50,而不是 5,但得到相同结果。


这是客户端 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 中标记为“无法修复”。此限制是针对每个浏览器 + 域的,因此这意味着您可以在所有选项卡上打开 6 个 SSE 连接到 www.example1.com 和另外 6 个 SSE 连接到 www.example2.com。(来自 Stackoverflow)。使用 HTTP/2 时,服务器和客户端之间协商同时 HTTP 流的最大数量(默认为 100)。

于 2020-06-17T11:33:29.033 回答