我想看看在重载机器之前我可以设置多少同步SSE(也就是EventSource)连接。但是使用Firefox(Firefox 18或Firefox 20)测试它在6个连接处停止:附加连接没有错误,但不发送任何数据。 (在Firebug中,我可以在那里看到它们,等待连接。) Chromium 25也在6个连接处停止,Opera 12.15也是如此。 但它似乎不是服务器端限制(我正在使用Apache + PHP),因为我可以同时运行所有三个浏览器(即18个连接),并且所有都来自相同的IP地址。 (服务器和客户端在同一台计算机上,但使用的是172.16.x.x地址,而不是127.0.0.1。)
因此,我使用CORS设置测试,并尝试连接到具有全局IP的另一台服务器。这次我获得了12个Firefox连接。建议它毕竟是Apache配置?不,Opera仍然只有6个连接。 (Chrome没有号码,因为CORS似乎不起作用。)我也可以连接到两台服务器,在Firefox中共有18个连接(但从不再连接),在Opera中共有12个连接。
作为第3次测试,我将后端和html都移动到远程服务器,并以这种方式加载页面。这次我达到了Firefox的10个连接限制!?! Opera仍有6的限制。而Chromium(由于此次没有涉及CORS,因此有限制)。限制为6。
我很欣赏任何关于这个数字6来自哪里的见解,以及所有三个浏览器是否相同只是巧合。特别是任何有关Firefox有时为6,有时为10,有时为12的洞察力。(SSE specification似乎未定义最大连接数。)
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行要取消注释和修改,如果你想试验连接到不同的服务器;这里给出它希望找到sse.php在同一目录中HTML):
<!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);
}
?>
答案 0 :(得分:11)
原因可能是每个EventSource对象都启动新的HTTP会话,实际上会打开新的tcp / ip套接字。由于您在无限循环中持续从服务器推送数据,因此套接字会持续打开。 所有Web浏览器都具有与同一服务器的并发活动连接的上限。根据RFC 2616,通常在4到6的范围内。您的浏览器只是阻止新连接打开,因为超出此限制。
您可以在这里了解更多信息:
http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/
答案 1 :(得分:2)
请参阅此处的每个主机名的连接列: 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 cannot be configured。
可以通过转到about:config
,然后打开“性能”并更改“最大持久连接服务器”来配置Opera。
的Safari?不,不可配置,apparently。
答案 2 :(得分: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)。