服务器如何跟踪实时数据推送场景中连接的所有客户端?
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实时推送网关技术