使用 HTTP keep-alive 和 websockets (socket.io) 时的 TCP 连接数

Posted

技术标签:

【中文标题】使用 HTTP keep-alive 和 websockets (socket.io) 时的 TCP 连接数【英文标题】:The number of TCP connections when using HTTP keep-alive and websockets (socket.io) 【发布时间】:2016-03-20 00:03:27 【问题描述】:

我已经实现了一个具有数据库驱动会话管理的成熟节点 http 服务器,并且已经能够在顶部使用 socket.io 来实现文件上传进度条和聊天应用程序。 我还使用了 node-http-proxy 并且能够代理 w​​ebsockets。在此背景下,我有以下问题,我相信我需要知道这些问题才能成为一名有效的 socket.io 开发人员。我没有陷入任何特定的代码,但下面要求的信息是必须成为有效的套接字开发人员,但似乎没有在任何地方解释。

我的理解:

一个。 HTTP 使用 TCP 套接字作为底层传输。 在旧的 HTTP 实现中,每个请求使用一个套接字。 在较新的版本中,“Keep-alive”标头用于使套接字保持活动状态,以便与多个请求-响应一起使用。 TCP 在其信令和数据传输方面本质上是全双工的,但在不能在同一连接上同时加载多个 HTTP 请求/响应的意义上说不是多路复用的。 keep-alive 标志有助于按顺序对 http 请求/响应事务使用相同的连接。

b. “升级” HTTP 标头用于将常规 http 连接升级到 websocket 连接。 websocket 连接实际上是现在在 http 协议级别抽象的基本 TCP 连接。

问题:在 websockets 握手之后,现在是有两个 TCP 连接还是只有一个被 http 用于全双工通信? 我的意思是,是否有一个用于常规 http 请求的 TCP 连接,而另一个用于诸如 socket.io 之类的库使用的双向传输? 换句话说,标头“升级”真的意味着升级现有 TCP 连接而不是打开新连接吗? 一个网页能否打开多个基于 ws 的 TCP 连接到同一台服务器?例如,同一页面中的两个聊天会话由同一台服务器管理? 在这种情况下,打开的 TCP 连接的总数是多少?它们是什么类型的?

我试图通过 netstat 获得一些答案,但我无法得出任何明确的结论。 Wireshark 可能会有所帮助,但我不擅长使用它。 任何澄清都会有所帮助。

【问题讨论】:

【参考方案1】:

websocket 连接实际上是现在在 http 协议级别抽象的基本 TCP 连接。

HTTP 是 TCP 之上的协议,WebSockets 也是 TCP 之上的协议。虽然 WebSockets 从编程方面看大多像普通套接字,但它不是纯 TCP。相反,有一些框架来获取消息边界而不是单个数据流,并且对数据进行了一些屏蔽,因此在使用 WebSockets 传输类似于 HTTP 的内容时不会拒绝愚蠢的代理。

HTTP 升级将底层 TCP 连接的协议从 HTTP 切换到 Websockets 协议。一旦切换完成,就没有回头路了。

一个网页可以打开多个基于ws的TCP连接到同一个服务器吗?

一个网页可以打开到同一个服务器的多个 HTTP 连接,每个连接都可以升级到 WebSockets。 Websockets RFC 的唯一限制是浏览器不应同时创建多个 Websockets 连接到同一主机,但不限制它们是在彼此之后创建并并行运行。

在这种情况下,打开的 TCP 连接的总数是多少?它们是什么类型的?

这取决于您的应用程序。每个 WebSockets 连接都会有一个 TCP 连接。此外,还会有其他 TCP 连接来获取 HTTP 资源。这些的确切类型(HTTP 与 HTTP/2)以及它们的数量取决于浏览器和服务器,即如果使用 keep-alive,则使用 HTTP/2 等。

【讨论】:

@Samir:浏览器可以有多个 Websockets 连接到同一个主机,它不应该同时创建它们(但一旦创建它们就会继续运行)。此外,Websockets 实际上是一个以 HTTP 请求为前缀的传输层协议,并且不限于请求-响应方案。这类似于 CONNECT 请求,该请求用于通过 HTTP 代理隧道传输 HTTPS(和 Websocket)。 @Samir:升级完成后,同一连接中没有常规的HTTP请求。一旦你升级到 Websockets 就没有回头路了。这也类似于 CONNECT 请求。整个概念类似于多级火箭。您只能从第一阶段(HTTP)到第二阶段(Websockets),但不能返回。 我考虑添加以下几点: 1. 使用keep-alive 并不能保证单个 HTTP 连接(较新的浏览器将使用 2-4 个连接来避免大响应阻塞信息流,较旧的浏览器会使用更多)。 2. 在upgrade 之后,连接是基于 TCP/IP 的 Websocket 协议,而不是 HTTP(我认为您在第一段末尾错误地写了 HTTP)。 3. 除非打开新连接,否则无法返回 HTTP。 4. 无法保证每个客户端将使用多少连接,尤其是在考虑 socket.io 的行为时。 @Myst: to 2) HTTP 是基于 TCP/IP 的,而 WebSockets 只是继续使用相同的底层 TCP/IP 连接。但是 WebSockets 不是普通的 TCP/IP。有一个额外的框架来获取消息而不是字符串,还有一个 XORing,这样愚蠢的代理就不会被混淆。 @SteffenUllrich - 至于 2)我知道额外的框架(我是 Iodine、Plezi's websocket 和 HTTP 服务器的作者)......但是不再有任何超文本传输协议(即请求->响应),因此我们将 HTTP 抛在脑后,使用 TCP/IP 上的 websocket 协议(即框架和掩码)进行通信。从 HTTP 升级到 HTTP/2 (htc) 或使用 ALPN 时也是如此——我们将旧协议抛在脑后,转而使用新协议。因此,它不再是 HTTP,尽管它是相同的 TCP/IP 连接。

以上是关于使用 HTTP keep-alive 和 websockets (socket.io) 时的 TCP 连接数的主要内容,如果未能解决你的问题,请参考以下文章

HTTP协议Keep-Alive模式详解和HTTP头字段总结

HTTP协议Keep-Alive模式详解和HTTP头字段总结

Http长连接和Keep-Alive以及Tcp的Keepalive

谈谈Http长连接和Keep-Alive以及Tcp的Keepalive

HTTP Keep-Alive模式

http协议Keep-Alive