SSE(EventSource):为什么不超过6个连接?

问题描述 投票:13回答:3

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

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

作为第三项测试,我将后端和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行;如此处给出的,它期望在与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);
    }
?>
apache google-chrome firefox opera server-sent-events
3个回答
14
投票

原因可能是每个EventSource对象都会启动新的HTTP会话,并且实际上会打开新的tcp / ip套接字。由于您要无限循环不断地推送来自服务器的数据,因此套接字会持续打开。所有Web浏览器对与同一服务器的同时活动连接都有上限。通常,根据RFC 2616的范围为4到6。您的浏览器只是阻止打开新连接,因为超出了此限制。

您也可以在这里了解更多信息:http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/


2
投票

请参阅此处的“每个主机名的连接数”列: http://www.browserscope.org/?category=network&v=1

比任何人可能想要的信息都要多,它表明观察到的“ 6”基本上只是惯例。

RFC2616建议限制为2,但每个人都忽略它。因此,http://trac.tools.ietf.org/wg/httpbis/trac/ticket/131删除了该建议。

自定义

看来可以从注册表中配置IE。

可以在about:config中配置Firefox,在network.http上进行过滤以进行各种设置; network.http.max-persistent-connections-per-server是要更改的那个。

当前是Chrome cannot be configured

可以通过转到about:config,然后打开“性能”并更改“最大持久连接服务器”来配置歌剧。

Safari?否,不可配置,apparently


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)。

© www.soinside.com 2019 - 2024. All rights reserved.