我认为为了回答这个问题,我们需要了解的是,在整个 WebSocket 创建过程中,底层 TCP 连接究竟是如何演变的。您将意识到WebSocket连接的关键部分是底层 TCP 连接本身。我不确定您在 WebSockets 上下文中的“会话”是什么意思。
在高层次上,启动“WebSocket 连接”需要客户端向 HTTP 服务器发送 HTTP GET 请求,而该请求包含Upgrade
标头字段。现在,为了让这个请求发生,客户端需要建立到 HTTP 服务器的 TCP 连接(这可能很明显,但我认为在这里明确指出这一点很重要)。随后的 HTTP 服务器响应随后通过相同的TCP 连接发送。
请注意,现在,在发送服务器响应后,如果客户端或服务器没有主动关闭 TCP 连接,TCP 连接仍然是打开/活动的。
现在,根据 RFC 6455,WebSocket 标准,在第 4.1 节的末尾:
如果服务器的响应按照上面的规定进行验证,则
表示WebSocket 连接已建立并且
WebSocket 连接处于 OPEN 状态
我从这里读到,客户端在发送初始 HTTP GET(升级)请求之前启动的同一 TCP 连接将保持打开状态,从现在开始将用作全双工 WebSocket 连接的传输层。这是有道理的!
关于您的问题,这意味着负载均衡器只会在发出初始 HTTP GET(升级)请求之前发挥作用,即在两个通信端点之间建立所述 WebSocket 连接创建所涉及的唯一一个 TCP 连接之前. 此后,TCP 连接保持建立,并且不能被中间的网络设备“重定向”。
我们可以得出结论——在你的会话术语中——TCP 连接定义了会话。只要 WebSocket 连接处于活动状态(即未终止),它就根据定义提供并存在于自己的会话中。没有什么可以改变这个会话。然而,在这张图片中,两个独立的 WebSocket 连接不能共享同一个会话。
如果您使用“会话”来引用其他内容,那么它可能是应用层引入的会话,我们无法对此发表评论。
编辑关于您的评论:
所以你说负载均衡器不参与 TCP 连接
不,这不是真的,至少在一般情况下是这样。它肯定会影响 TCP 连接的建立,从某种意义上说,它可以决定如何处理客户端连接尝试。具体取决于负载均衡器的确切类型(*,见下文)。重要提示:在两个端点之间建立连接后——虽然我不认为负载均衡器是一个端点,但我指的是 WebSocket 客户端和 WebSocket 服务器——这两个端点在 WebSocket 连接的生命周期内将不再改变. 负载均衡器可能*仍在网络路径中,但可以假定不再受到影响。
因此全双工连接是在客户端和端服务器之间?
是的!
***有不同类型的负载平衡。根据类型的不同,负载均衡器在两个端点之间建立连接后的作用是不同的。例子:
- 如果负载平衡发生在 DNS 基础上,那么负载平衡器根本不参与最终的 TCP 连接。它只是告诉客户端必须直接连接到哪个主机。
- 如果负载均衡器的工作方式类似于 AWS 的第 4 层 ELB(此处的文档),那么可以说代理 TCP 连接。因此,客户端实际上会将 ELB 本身视为服务器。然而,发生的情况是 ELB 只是在两个方向上转发包,而不做任何更改。因此,它仍然大量参与 TCP 连接,只是透明的。在这种情况下,实际上涉及两个永久 TCP 连接:一个从您到 ELB,一个从 ELB 到服务器。在您的 WebSocket 连接的整个生命周期内,这些都是永久性的。