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

3
我已经实现了一个完整的Node HTTP服务器,并带有基于数据库的会话管理,还能够在其上使用Socket.io来实现文件上传进度条和聊天应用程序。 我还使用了node-http-proxy,并且能够代理WebSockets。在这个背景下,我有以下问题,我相信我需要知道这些才能成为一个有效的socket.io开发人员。我没有被困在任何具体的代码中,但是下面请求的信息对于成为有效的套接字开发人员是必须了解的,但似乎没有任何地方解释过。
我的理解: a. HTTP使用TCP套接字作为底层传输。在旧版HTTP实现中,每个请求使用一个套接字。在新版中,“Keep-alive”标头用于保持套接字活动以供多次请求-响应使用。TCP在其信令和数据传输方面本质上是全双工的,但在多个HTTP请求/响应不能同时加载到同一连接上的意义上不是复用的。keep-alive标志有助于在序列中使用相同的连接进行http请求/响应事务。
b. “upgrade” HTTP标头用于将常规http连接升级为websocket连接。 websocket连接实际上是在http协议级别抽象化的基本TCP连接。
问题:在WebSockets握手之后,现在是否有两个TCP连接还是只有一个TCP连接用于全双工通信? 我的意思是,是否有一个TCP连接用于常规http请求,现在有另一个用于双向传输,像socket.io这样的库使用? 换句话说,“升级”标头是否真正意味着升级现有的TCP连接而不是打开新连接? 一个网页可以打开多个基于ws的TCP连接到同一服务器吗?例如,在同一页中由同一服务器管理的两个聊天会话? 在这种情况下,将打开多少个TCP连接以及它们的类型是什么?
我尝试使用netstat获取一些答案,但我无法得出任何明确的结论。 Wireshark可能有所帮助,但我不擅长使用它。 任何澄清都将有所帮助。
1个回答

4
WebSocket连接实际上是基本的TCP连接,现在已在http协议级别进行了抽象。HTTP是TCP之上的协议,WebSocket也是TCP之上的协议。虽然WebSocket在编程方面看起来大多像普通套接字,但它并不是纯TCP。相反,为了获得消息边界而不是单个数据流以及对数据进行一些屏蔽,以便使用WebSocket传输类似HTTP的内容时,不会拒绝愚蠢的代理。
HTTP升级将底层TCP连接的协议从HTTP更改为WebSockets协议。一旦完成切换,就没有回头的路了。
一个网页可以打开多个到同一服务器的HTTP连接,并且每个连接都可以升级到WebSockets。 Websockets RFC 的唯一限制是浏览器不应同时创建多个Websockets连接到同一主机,但是没有限制它们是连续创建并行运行的。
这取决于您的应用程序。每个WebSockets连接将有一个TCP连接。此外,还将有其他TCP连接以获取HTTP资源。这些的确切类型(HTTP vs HTTP/2)和数量取决于浏览器和服务器,即是否使用持久连接、使用HTTP/2等。

1
@Samir:浏览器可以与同一主机建立多个Websockets连接,但不应同时创建它们(但一旦创建,它们将继续运行)。此外,Websockets实际上是一个以HTTP请求为前缀的传输层协议,并且不限于请求-响应方案。这类似于CONNECT请求,用于通过HTTP代理隧道传输HTTPS(和Websockets)。 - Steffen Ullrich
1
@Samir:升级完成后,同一连接中没有常规的HTTP请求。一旦您升级到Websockets,就无法返回。这也类似于CONNECT请求。整个概念类似于多级火箭。您只能从第一阶段(HTTP)到第二阶段(Websockets),但不能返回。 - Steffen Ullrich
1
我考虑添加以下几点:1.使用keep-alive不能保证单个HTTP连接(新版本的浏览器会使用2-4个连接以避免大型响应阻塞信息流,而旧版本则会使用更多)。2.upgrade之后,连接是基于TCP/IP的Websocket协议,而不是HTTP(我认为你在第一段末尾写错了HTTP)。3.除非打开一个新连接,否则无法返回HTTP。4.无法保证每个客户端将利用多少连接,特别是考虑到socket.io的行为。 - Myst
1
@Myst:对于第二点,HTTP是基于TCP/IP的,而WebSocket继续使用相同的底层TCP/IP连接。但WebSocket不仅仅是普通的TCP/IP。它还有一个额外的框架来获取消息而不是字符串,并且还有异或操作,以防止愚蠢的代理混淆。 - Steffen Ullrich
1
@SteffenUllrich - 是的,更清晰了。这是一个非常清晰简洁的答案。至于(1)和(4),我会考虑在回答正在使用的连接总数时引用末尾的信息。你的答案似乎是指最终状态,但忽略了浏览器加载资源时使用的连接。无论如何,你有我的支持 :-) - Myst
显示剩余10条评论

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