问题标签 [eventsource]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
8 回答
38976 浏览

node.js - Websocket 传输可靠性(重新连接期间的 Socket.io 数据丢失)

用过的

NodeJS,Socket.io

问题

想象有 2 个用户U1U2,通过 Socket.io 连接到一个应用程序。算法如下:

  1. U1完全失去互联网连接(例如关闭互联网)
  2. U2向U1发送消息。
  3. U1尚未收到消息,因为 Internet 已关闭
  4. 服务器通过心跳超时检测U1断线
  5. U1重新连接到 socket.io
  6. U1永远不会收到来自U2的消息- 我猜它在第 4 步丢失了。

可能的解释

我想我明白为什么会这样:

  • 在第 4 步上,服务器也终止了套接字实例和发送到U1的消息队列
  • 此外,在第 5 步U1服务器创建新连接(它不被重用),所以即使消息仍在排队,之前的连接无论如何都会丢失。

需要帮忙

如何防止这种数据丢失?我必须使用心跳,因为我不会让人们永远挂在应用程序中。此外,我仍然必须提供重新连接的可能性,因为当我部署新版本的应用程序时,我希望零停机时间。

PS 我称之为“消息”的东西不仅仅是我可以存储在数据库中的文本消息,而是有价值的系统消息,必须保证交付,否则 UI 会搞砸。

谢谢!


加法1

我已经有一个用户帐户系统。而且,我的应用程序已经很复杂了。添加离线/在线状态无济于事,因为我已经有了这种东西。问题是不同的。

查看第 2 步。在这一步中,我们在技术上不能说 U1 是否离线,他只是失去连接让我们说 2 秒钟,可能是因为网络不好。所以 U2 向他发送了一条消息,但 U1 没有收到它,因为他的互联网仍然关闭(第 3 步)。需要第 4 步来检测离线用户,假设超时为 60 秒。最终,再过 10 秒,U1 的互联网连接就建立起来了,他重新连接到了 socket.io。但是来自 U2 的消息在空间中丢失了,因为服务器 U1 因超时而断开连接。

这就是问题所在,我不想 100% 交货。


解决方案

  1. 在 {} 用户中收集发射(发射名称和数据),由随机发射 ID 标识。发送发射
  2. 在客户端确认发射(使用 emitID 将发射发送回服务器)
  3. 如果确认 - 从由 emitID 标识的 {} 中删除对象
  4. 如果用户重新连接 - 为该用户检查 {} 并循环遍历它,为 {} 中的每个对象执行第 1 步
  5. 必要时为用户断开连接或/和连接刷新 {}

解决方案2(有点)

2020 年 2 月 1 日添加。

虽然这并不是 Websockets 的真正解决方案,但有人可能仍然觉得它很方便。我们从 Websockets 迁移到 SSE + Ajax。SSE 允许您从客户端连接以保持持久的 TCP 连接并实时接收来自服务器的消息。要将消息从客户端发送到服务器 - 只需使用 Ajax。有延迟和开销等缺点,但 SSE 保证可靠性,因为它是 TCP 连接。

由于我们使用 Express,因此我们将此库用于 SSE https://github.com/dpskvn/express-sse,但您可以选择适合您的库。

IE 和大多数 Edge 版本不支持 SSE,因此您需要一个 polyfill:https ://github.com/Yaffle/EventSource 。

0 投票
1 回答
814 浏览

http - Firefox 未收到 EventSource 消息

我有一个发送测试EventSource消息的服务器,如下所示:

要求:

回复:

所有行都以\r\n. 所以这对我来说是正确的,但如果我在 Firefox 中尝试这个......

...然后它完全按照上面的方式连接并执行请求(实际上我将会话从 Wireshark 复制到 telnet 以对其进行测试),并根据 Wiresharkevent: data发送了内容,但既不调用onmessage也不onerror调用处理程序。onerror当我停止服务器时调用。

网络事物的响应选项卡中从未显示任何数据。

有谁知道出了什么问题?

0 投票
3 回答
844 浏览

javascript - 如何捕获 SSE 事件源确认

我正在使用此代码向浏览器客户端发送 SSE 消息。

https://nodejs.org/api/http.html#http_response_write_chunk_encoding_callback

节点服务器

对于我使用这个javascript的客户端:

一切正常,但是服务器如何确定客户端确实收到了它?我猜 SSE 正在使用 TCP,有什么方法可以收到确认吗?

0 投票
1 回答
1573 浏览

ruby-on-rails - 如何创建类似于 javascript 节流/去抖动功能的 Rails/Ruby 方法

在我们的应用程序中,我们公开了一个回调路由以供外部服务命中。当我们收到回调时,我们使用客户端/浏览器端的 Eventsource 和服务器端的 cramp 向客户端订阅者发布更新。然而,有时我们会被来自这个外部服务的回调请求轰炸,这导致我们向客户端发布大量更新。Rails 端有没有一种方法,类似于 javascript debounce 函数,可以在收到的回调之间等待一段设定的时间来发布消息?

我们已经在使用 sidekiq + 线程,因此欢迎使用这些工具提出建议。

0 投票
0 回答
56 浏览

node.js - 服务器事件流式传输是否有字符限制?

我正在处理流式服务器事件(EventSource),我需要通过它发送非常大的 JSON。有字数限制吗?如果消息太长,消息会被剪掉还是不发送?我在网上找不到任何相关的东西。

0 投票
1 回答
146 浏览

php - 在 php 中订阅 ServerSentEvents

我有一个发布事件的端点,我希望我的 php API 订阅事件并触发响应。可能吗?我知道在 nodejs 中我可以使用 Eventsource 库来订阅端点。PHP中的等价物是什么?

0 投票
0 回答
192 浏览

php - 将 php 流套接字与 eventSource 相结合

我正在尝试了解 PHP 中的套接字,并且大量阅读使我走上了stream_socket_server().

我使用类似于下面的代码在 linux 的两个终端之间进行了基本的聊天,并希望我的下一步是在网络上构建聊天或通知系统。

我期望发生的事情:

eventSource.html 中的事件侦听器将侦听 while 循环中的事件并输出从正在运行 server.php 的 linux 终端接收到的消息

怎么了:

从 eventSource.html 的角度来看,一切都在正常工作。因此,如果我要取消此操作的全部目的并仅将消息替换为标准字符串,那么它将每秒Hello World成功输出。<li>message:{Hello World}</li>

但是,一旦我尝试从终端读取数据,除了<li>message: {}</li>每秒之外,什么都没有出现。值得注意的是,当我运行 server.php 时,它会等待客户端,然后当我运行 eventSource.html 时,它会成功连接。

我误解了这是如何工作的?我假设在 while 循环中的每一秒它都会查找该流中的数据。

或者我在学习套接字方面走的是一条完全错误的道路。

server.php (我从 linux 的终端加载它)

client.php 从下面的 eventSource.html 加载

事件源.html

0 投票
3 回答
19181 浏览

json - 可以通过 POST 使用 EventSource 传递参数的服务器发送事件 (SSE)

我正在使用 Html5 服务器发送事件。服务器端是 Java Servlet。我有一个 json 数组数据想要传递给服务器。

如果数组大小很小,则服务器端可以获取查询字符串。但是如果数组大小很大。(可能超过数千个字符),服务器无法获取查询字符串。是否可以使用 POST 方法new EventSource(...)将 json 数组传递给可以避免查询字符串长度限制的服务器?

0 投票
0 回答
267 浏览

.net - 如何在没有管理员权限的情况下创建 EventSource?

我有一个场景,我必须在没有管理员权限的情况下创建事件源,因为应用程序需要在运行时执行它。

安装程序以管理员权限执行,所以我可以做些什么来修改需要修改的任何内容,以避免需要管理员权限。

有什么我可以改变的,比如注册表项的权限、安全策略或允许普通用户创建事件源的东西吗?

0 投票
0 回答
432 浏览

python - Flask:如何检测无限响应发生器中的断开连接?

烧瓶中,我有一个用于EventSource接收更新/事件的页面。

它以相当简单的方式实现:

我遇到的问题是,每次我重新加载连接EventSource到我的“更新”页面的页面时,它都会创建一个新线程来服务该“更新”请求。它永远不会死

有更新通过,所以这意味着它正在将数据推送到某个地方,使我的服务器使用越来越多的线程和越来越多的内存。

我希望得到的简单解决方案是while True用某种形式的while is_connected().

但是我似乎无法找到一种方法来检测浏览器是否仍然连接。

问题:如何检查我的生成器内部的连接是否仍然存在?

编辑

查看代码,它似乎应该调用close()生成器,所以理论上它应该GeneratorExit在我的gen().

但是,我没有看到任何这种情况发生的痕迹,并且每次调用都会pstree在每次请求/连接到/updates.