在什么情况下,我的浏览器会尝试重复使用TCP连接来进行多个请求?

13

我使用的是Firefox浏览器,但我想知道浏览器通常是如何决定这个的。

当我在短时间内两次访问同一个URL时,我的浏览器似乎会尝试重用TCP相同的连接来处理这两个请求(这被称为keep-alive)。然而,当我访问两个不同的URL(但仍由同一服务器提供)时,浏览器有时会决定为每个请求打开一个新的连接。显然,浏览器没有使用一连接一URL的策略。

我之所以问这个问题,是因为我正在尝试实现一个使用长轮询的Web服务。我可以想象用户可能希望在同一浏览器的多个选项卡中打开此服务。然而,在使用keep-alive时,第二个长轮询请求不会被发送,直到第一个请求完成(至少在Firefox中),因为浏览器正在尝试将它们都塞进同一个套接字中,这是我设计服务时没有预料到的。即使浏览器实现了管道化,我也无法在响应第一个请求之前响应第二个请求,因为HTTP要求我按顺序完成响应。

1个回答

8
在使用HTTP/1.1时,默认情况下,TCP连接会保持打开以便重用。这是为了比每个请求都启动新的连接而获得更好的性能。该连接可以被重用,但连接可能会被任何一方随时关闭。
您应该阅读HTTP1.1和持久连接部分。
在您的情况下,它甚至没有使用HTTP pipelining(不广泛支持),因为下一个请求是在第一个响应之后发送的。
浏览器有一个连接池,并针对每个主机名重复使用它。一般来说,浏览器不应该为多个主机名重用单个连接,即使这些主机名实际上解析到相同的IP地址。
大多数浏览器允许用户配置或覆盖每个服务器的持久连接数量;大多数现代浏览器默认为六个。如果Firefox确实因为已经存在活动连接而阻止第二个请求,则这是Firefox中的错误,并且应该在其错误跟踪系统中进行记录。但是,如果存在这样的错误,我认为您会看到许多网站无法正常工作。

也许对于相同的URL,它会尝试使用相同的连接,但对于不同的URL,它会在池中选择另一个连接? - Mark
如果您的测试是向同一URL发送2个“并发”的HTTP请求,那么您可能会看到它们被“串行化”或者通过2个不同的TCP连接发送。但是您并没有看到它们被“流水线化”。现在会发生什么取决于实现。例如,浏览器可以选择重用池中的连接,或者将第二个请求发送到一个新的连接上。这两种方法都是正确的,因为HTTP是一个“无状态”的协议。如果您的实现依赖于这些细节,那么在我看来,您的设计存在缺陷。也许您应该更多地写一些关于您想要实现的内容。 - Cratylus
@马克:你是怎么解决这个问题的?我也遇到了同样的情况:我的长轮询服务器端程序从多个打开相同页面的标签中只接收1个请求。结果,我的数据在选项卡之间循环分配。 - peroksid
@peroksid:哇,这是很久以前的事了。我想我最终采取了一些hacky的方法,比如让客户端请求URL时在末尾附加一个随机查询字符串。 - Mark
谢谢回复。我希望能找到一种服务器端的解决方案,以便让我的客户端同事的工作更轻松些。 - peroksid
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接