坚持使用自定义过滤器获取实时数据的方法
Stuck on approach for real-time data with custom filters
我已经挠头尝试了大约一个星期了。所以我希望我能在这里找到我的帮助..
我正在制作一个向客户端提供实时数据的应用程序,我考虑过 Server-Sent-Events 但它不允许每个用户响应 AFAIK。
WebSocket 也是一个选项,但我不相信它,让我描绘一下我用 WS 做的场景:
- 服务器每秒获取 20 条记录,并将它们推送到数组
- 这个数组每秒发送到所有 websocket 连接,见下面这个伪:
let items = [ { ... some-data ... } ];
io.on("connection", socket => {
setInterval(() => {
io.emit("all_items", items);
}, 1000);
});
- 用户可以在前端select一些项目,websocket接收这个每个连接
但是,我深信我采用的方法不是一个好方法,而且效率非常低。让我勾勒一下我想要实现的程序的场景:
- 假设有一个数据库有 1.000 条记录
- 用户从(React)前端连接到后端,连接到主 "stream" 大约有 20 条获取的记录(没有过滤器),服务器每秒获取一次。
SELECT * FROM Items LIMIT 20
复杂的部分来了:
- 用户点击了一些带有自定义过滤器的复选框(在前端),例如
location = Shelf 2
。现在,应该发生的是 websocket 总是显示该用户的 20 条记录,无论过滤器是什么
我曾设想为每个用户使用自定义选项进行自定义查询,但我认为这很糟糕,如果您有 10.000 个用户,这绝对会破坏服务器
我怎么能接受这个?拜托,一切都有一点帮助,提前谢谢你。
我必须对您的应用进行一些猜测。让我试着在谈论服务器的功能时把它拼出来,而不提及 MySQL 或任何其他数据库。
我猜您的服务器维护着大约 1k 个具有易变值的数据点。 (它可能使用 DBMS 来维护这些值,但让我们暂时忽略该机制。)我猜您的应用程序中的某些进程会根据某种外部刺激更改这些值。
您的客户端在第一次连接到您的服务器时,开始每秒接收一次这些值中的 20 个子集。 您没有指定如何选择初始子集。 所有新连接的客户端都获得相同的 20 个值。
客户端可以在连接时应用过滤器。当他们这样做时,他们开始从您拥有的所有价值观中得到一个不同的、经过过滤的子集。他们仍然得到二十个值。部分或全部值可能仍在初始集中,有些可能不在。
我猜客户端每秒为相同的二十个数据点.
获取更新值
您设想 运行 具有许多连接客户端的大规模应用程序。
这里有一些关于系统设计的想法。
- 以合适的数据结构将数据点保存在 RAM 中。
- 编写 js 代码以将客户端指定的过滤器应用于该数据结构。如果该代码高效,您可以通过这种方式处理数百万个数据点。
- 将该 RAM 数据结构备份到您选择的 DBMS; MySQL 可以。
- 当您的服务器首次启动时,从数据库加载数据结构。
要达到您提到的规模,您需要在至少五台服务器上对所有这些进行负载平衡。您没有提到更新数据点的过程,但它必须以某种方式分散到多个服务器。你需要记住这一点。根据您提供给我们的信息,我们无法就此向您提供建议。
但是,YAGNI。让事情运转起来,然后弄清楚如何扩大规模。 (获得 10,000 名用户真的很辛苦;花时间让您的应用程序对前 10 个用户、然后是 100 个用户非常出色,然后再扩大规模。)
您的服务器与客户端的交互是这样的(忽略身份验证等)。
- 客户端连接,隐式请求 "no-filtering" 过滤器。
- 客户端每秒推送一次二十个值。
- 客户端可以随时隐式请求不同的过滤器。
- 然后客户端继续获得二十个值,由所选过滤器选择。
因此,大多数客户端通信被推出,偶尔传入过滤请求。
这种大量下行流量和少量上行流量是服务器发送事件的理想方案。 Websockets 或 socket.io 也可以。你可以这样构造它。
新客户端连接到位于 https://example.com/stream
的 SSE 端点
应用过滤器时,他们会重新连接到位于 https://example.com/stream?filter1=a&filter2=b&filter3=b
的另一个 SSE 端点
服务器每秒向应用过滤器的每个打开的 SSE 连接发送数据。 (在 nodejs 中,Streams 工作得很好;看一下 server side code for the signalhub 包的例子。
我已经挠头尝试了大约一个星期了。所以我希望我能在这里找到我的帮助..
我正在制作一个向客户端提供实时数据的应用程序,我考虑过 Server-Sent-Events 但它不允许每个用户响应 AFAIK。
WebSocket 也是一个选项,但我不相信它,让我描绘一下我用 WS 做的场景:
- 服务器每秒获取 20 条记录,并将它们推送到数组
- 这个数组每秒发送到所有 websocket 连接,见下面这个伪:
let items = [ { ... some-data ... } ];
io.on("connection", socket => {
setInterval(() => {
io.emit("all_items", items);
}, 1000);
});
- 用户可以在前端select一些项目,websocket接收这个每个连接
但是,我深信我采用的方法不是一个好方法,而且效率非常低。让我勾勒一下我想要实现的程序的场景:
- 假设有一个数据库有 1.000 条记录
- 用户从(React)前端连接到后端,连接到主 "stream" 大约有 20 条获取的记录(没有过滤器),服务器每秒获取一次。
SELECT * FROM Items LIMIT 20
复杂的部分来了:
- 用户点击了一些带有自定义过滤器的复选框(在前端),例如
location = Shelf 2
。现在,应该发生的是 websocket 总是显示该用户的 20 条记录,无论过滤器是什么
我曾设想为每个用户使用自定义选项进行自定义查询,但我认为这很糟糕,如果您有 10.000 个用户,这绝对会破坏服务器
我怎么能接受这个?拜托,一切都有一点帮助,提前谢谢你。
我必须对您的应用进行一些猜测。让我试着在谈论服务器的功能时把它拼出来,而不提及 MySQL 或任何其他数据库。
我猜您的服务器维护着大约 1k 个具有易变值的数据点。 (它可能使用 DBMS 来维护这些值,但让我们暂时忽略该机制。)我猜您的应用程序中的某些进程会根据某种外部刺激更改这些值。
您的客户端在第一次连接到您的服务器时,开始每秒接收一次这些值中的 20 个子集。 您没有指定如何选择初始子集。 所有新连接的客户端都获得相同的 20 个值。
客户端可以在连接时应用过滤器。当他们这样做时,他们开始从您拥有的所有价值观中得到一个不同的、经过过滤的子集。他们仍然得到二十个值。部分或全部值可能仍在初始集中,有些可能不在。
我猜客户端每秒为相同的二十个数据点.
获取更新值您设想 运行 具有许多连接客户端的大规模应用程序。
这里有一些关于系统设计的想法。
- 以合适的数据结构将数据点保存在 RAM 中。
- 编写 js 代码以将客户端指定的过滤器应用于该数据结构。如果该代码高效,您可以通过这种方式处理数百万个数据点。
- 将该 RAM 数据结构备份到您选择的 DBMS; MySQL 可以。
- 当您的服务器首次启动时,从数据库加载数据结构。
要达到您提到的规模,您需要在至少五台服务器上对所有这些进行负载平衡。您没有提到更新数据点的过程,但它必须以某种方式分散到多个服务器。你需要记住这一点。根据您提供给我们的信息,我们无法就此向您提供建议。
但是,YAGNI。让事情运转起来,然后弄清楚如何扩大规模。 (获得 10,000 名用户真的很辛苦;花时间让您的应用程序对前 10 个用户、然后是 100 个用户非常出色,然后再扩大规模。)
您的服务器与客户端的交互是这样的(忽略身份验证等)。
- 客户端连接,隐式请求 "no-filtering" 过滤器。
- 客户端每秒推送一次二十个值。
- 客户端可以随时隐式请求不同的过滤器。
- 然后客户端继续获得二十个值,由所选过滤器选择。
因此,大多数客户端通信被推出,偶尔传入过滤请求。
这种大量下行流量和少量上行流量是服务器发送事件的理想方案。 Websockets 或 socket.io 也可以。你可以这样构造它。
新客户端连接到位于
https://example.com/stream
的 SSE 端点
应用过滤器时,他们会重新连接到位于
https://example.com/stream?filter1=a&filter2=b&filter3=b
的另一个 SSE 端点
服务器每秒向应用过滤器的每个打开的 SSE 连接发送数据。 (在 nodejs 中,Streams 工作得很好;看一下 server side code for the signalhub 包的例子。