服务器如何跟踪实时数据推送场景中连接的所有客户端?



我有点理解Websocket是用于实时数据来回流动的协议。

我的问题可能非常成熟,但在网络上找不到太多帮助。

假设 1000 个客户端连接到发送实时股票价格的服务器。当服务器端有更新时,服务器如何知道需要向其发送更新的所有 1000 个客户端?

如果这是在服务器端发生的某种循环,其中缓存了所有连接的客户端详细信息,然后将更新发送给所有这些客户端,这不是开销吗?

这个 SOF 的回答有些道理,但并没有消除我的疑虑。

服务器如何跟踪实时数据推送场景中连接的所有客户端?

它不...它只跟踪它专门服务的客户端。

这个答案不是节点.js具体的。

假设 1000 个客户端连接到发送实时股票价格的服务器。当服务器端有更新时,服务器如何知道需要向其发送更新的所有 1000 个客户端?

为了更好地理解这一点,我们应该考虑更大的数字。 即,假设有 100 万个客户端连接到服务。

显然,一个合理的设计将需要冗余,因此没有一个服务可以容纳所有 100 万个连接(如果单个服务器实例失败,客户端可以重新连接到不同的服务器实例)。

在这种情况下,没有单个服务器知道所有客户端。

每个服务器管理自己的内部订阅/客户端列表更有意义。每个服务器还将充当集中式发布/订阅服务(例如 Redis 集群或其他服务)的发布/订阅客户端。

假设 1000 个服务器实例,每个实例为 1000 个客户端提供服务,我们会发现发布/订阅服务只知道 1,000 个"客户端"(服务器实例)。每个服务器都不知道其他客户端,它只知道它正在管理的 1,000 个客户端。

如果这是在服务器端发生的某种循环,其中缓存了所有连接的客户端详细信息,然后将更新发送给所有这些客户端,这不是开销吗?

算法本身是特定于实现的,但通常,每个服务器都会产生一些开销来管理发布/订阅层。

但是,由于每台服务器仅管理客户端总数的一小部分,因此开销分布在多个系统中。

面向通道的设计与面向连接的设计

我可能应该注意到,发布/订阅设计不是面向连接的。

服务器没有(或不应该)遍历所有连接,询问"您是否订阅了此频道"?

相反,发布/订阅设计假定面向"通道"的设计,其中它定位通道对象并循环访问客户端列表。

一方面,此方法可能会(或可能不会)消耗更多内存。由于每个"通道"都应包含侦听该通道的客户端列表,因此单个客户端对象可能属于多个列表。

另一方面,与面向连接的设计相比,循环具有更少的代码分支,并且经历的开销更少。此外,此方法允许未绑定连接的发布/订阅客户端(例如内部挂钩/回调)。

假设1000个客户端连接到发送实时股票价格的服务器。当服务器端有更新时,服务器如何知道需要向其发送更新的所有 1000 个客户端?

Socket.io 已经自行跟踪,并且很容易发送到所有连接的客户端。

Socket.io - 发出备忘单

如果您担心用户群增长时会发生什么,您可以将服务扩展到多个节点。

如果您实际上最终扩展并且拥有多个服务器节点,则可以使用套接字-雷迪斯

Adapter to enable broadcasting of events to multiple separate socket.io server nodes.

最新更新