websocket - 可以在客户端实时更新数据
问题描述
我有以下场景,我想知道它是否可能/可行。如果这被认为是一个过于“宽泛”的问题,我深表歉意,但我认为 SO 是提出这个问题的最佳场所。
让我们假设我有一个网站,我想向最终用户显示一个图表。出于本示例的目的,假设我们要向他们显示过去一小时内的“每个类别的销售额”。数据将显示在图表中,运行查询的 SQL 可能是这样的:
SELECT SUM(revenue) FROM sales
WHERE timestamp > NOW() - INTERVAL 1 HOUR
GROUP BY category
据我所知,有两种通用方法可以为最终用户更新数据:
- 以一定的时间间隔进行某种轮询(或类似技术)以从查询中重新获取数据。但是,这可能会变得非常昂贵,具体取决于查询的复杂性/持续时间以及同时连接的人数。
- 第二种方法是将所有数据存储在内存中并将更新直接推送到该内存存储(可以是客户端或服务器端,只要有数据,我们就可以向最终用户发送 ws 请求更新。这方面的一个例子是使用类似https://github.com/jpmorganchase/perspective的东西。
那么我的问题是,当数据太大而无法存储在内存中时,是否有可能进行实时数据更新(我在示例 2 中描述的情况)。我认为答案是“不”,但也许我错过了一些方法来做到这一点。例如,假设我在 BigQuery 中存储了 1TB 的数据,并且我正在通过购买新产品对其进行流式更新——有没有一种方法可以将更新推送到最终客户端,而不必每次都重新运行查询想要获得更新?是否有任何其他技术可以用于这种情况/有用?
同样,我认为这是不可能的,但我想看看在查询的数据集上尽可能近实时地向终端客户端显示什么是可能的。
解决方案
如果您的数据对于每个客户端都是唯一的、大而实时的变化,那么使用任何数据库或缓存作为交换都没有任何好处。您必须直接发送数据更新。
如果您不能直接将数据从执行数据库更新的进程推送到客户端,您可能可以通过消息代理将数据从执行更新的进程传递到执行推送的进程(我将使用 Rabbitmq 作为示例)。
此设置的最佳配置是主题模型,其中主题是客户端 ID 或键,并为该主题为每个连接的客户端创建一个侦听器 - 或者,为所有客户端设置一个侦听器,但动态注册/取消注册主题。
让 websocket 处理程序监听他们客户端的主题。设置更新数据库的过程,以将更新流式传输到客户端的主题 ID。代理将丢弃所有未发送到已连接客户端的更新,从而使侦听器端的负载更易于管理。
无需任何存储或轮询,此解决方案具有低延迟。即使有 1000 个同时存在的客户,我怀疑代理是否会耗尽内存。
推荐阅读
- swift - 使用 MFMailComposeViewController 时应用程序崩溃
- angular - testing angular template driven forms
- ansible - Ansible:加快查找和链接文件的速度
- node.js - Firefox 无法建立与 socket.io 的连接
- ruby-on-rails - Rails 凭据:编辑和未初始化的常量 Bundler (NameError)
- asp.net - ASP.NET OWIN Azure 广告登录在 iPhone (Safari) 浏览器上不起作用。在其他浏览器上很好
- angular - 无法绑定到“matMenuTriggerFor”,因为它不是“按钮”的已知属性
- javascript - 保证promise运行顺序,Word API JS
- php - How to avoid repeating similar sections of MySQL query code in PHP?
- javascript - How is this fat arrow operating in this code?