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

Posted

技术标签:

【中文标题】服务器如何跟踪实时数据推送场景中连接的所有客户端?【英文标题】:How does Server keep track of all Client(s) connected in Real time data pushing scenario? 【发布时间】:2019-06-18 08:35:21 【问题描述】:

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

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

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

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

This SOF answer 有点道理,但并没有消除我的疑问。

【问题讨论】:

【参考方案1】:

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

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

Socket.io - Emit Cheatsheet

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

如果您实际上最终扩展并拥有多个服务器节点,那么您可以使用 socketio-redis

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

【讨论】:

这有点回答我的问题,但一旦我从我的终端尝试 socket.io,就会将其标记为已接受的答案。非常感谢:)【参考方案2】:

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

它不...它只跟踪它专门保存的客户端。

这个答案不是 node.js 特定的。

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

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

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

在这种情况下,没有一个服务器可以识别所有客户端。

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

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

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

算法本身是特定于实现的,但一般来说,每个服务器都会产生一些开销来管理 pub/sub 层。

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

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

我应该注意到 pub/sub 设计不是面向连接的。

服务器没有(不应该)循环所有连接询问“你订阅了这个频道吗?”。

相反,发布/订阅设计采用面向“通道”的设计,它定位通道对象并在客户端列表上循环。

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

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

【讨论】:

以上是关于服务器如何跟踪实时数据推送场景中连接的所有客户端?的主要内容,如果未能解决你的问题,请参考以下文章

即时通讯开发长连接网关技术:WebSocket实时推送网关技术

php是如何实现websocket实时消息推送的

winform上如何实现服务器消息实时推送?

关于云开发新服务“实时数据推送”,你需要了解的全在这了!

Android 心跳包心跳连接 如何实现android和服务器长连接呢?推送消息的原理

推送原理解析 极光推送使用详解