12

在我深入研究代码之前,有人可以告诉我是否有任何文档可用于在 Socket.IO 中确认交付?

到目前为止,这是我能够收集到的内容:

  1. 可以提供回调以在消息被确认时调用
  2. 有一种特殊模式“volatile”不保证交付
  3. 有一个不是“易失性”的默认模式

这给我留下了一些问题:

  1. 如果消息不是易失性的,它是如何处理的?会无限期缓冲吗?
  2. 如果无法在合理的时间内传递消息,是否有任何方法可以得到通知?
  3. 如果我想放弃,有什么办法可以取消缓冲消息?

对于如何在时间敏感的应用程序中使用 Socket.IO 而不会退回到易失性模式并使用可以提供故障事件和某种程度的可配置性的外部 ACK 层,我有点不知所措。还是我错过了什么?

4

2 回答 2

13

TL;DR 除非您愿意等到宇宙消亡,否则您无法获得可靠的确认交付。


您寻求的交货确认与理论上的两个将军问题有关,该问题也在此 SO 答案中进行了讨论。

TCP 通过保证无限重试后的传递来管理可靠性问题。我们生活在一个有限的宇宙中,所以“保证”这个词在理论上是可疑的 :-)

抛开理论不谈,考虑一下:engine.io是 socket.io 1.x 的基础,使用以下传输:

  • 网络套接字
  • 闪存插座
  • XHR 轮询
  • JSONP 轮询

这些传输中的每一个都基于 TCP,而 TCP 是可靠的。因此,只要连接保持连接并且传输不改变,每个单独的 socket.io 消息或事件都应该是可靠的。但是,有两件事情可能会即时发生:

  1. engine.io 可以改变传输
  2. 如果底层传输断开连接,socket.io 可以重新连接

那么,当客户端或您的服务器在管道被这样摆弄时喷出一些消息时会发生什么?在engine.io 协议socket.io 协议(在撰写本文时分别为版本 3 和 4)中都没有说明。

正如您在评论中所建议的那样,实现中有一些确认逻辑。但是,即使是简单的数字通信也没有不重要的行为,所以我不相信无监督的 socket.io 连接可以可靠地交付任务或安全关键操作。在可靠交付成为他们协议的一部分并且他们的方法得到独立和正式验证之前,这种情况不会改变。

欢迎您采用我的政策:

  • 给我的消息编号
  • 有疑问时要求重新发送
  • 不要改变我的状态——客户端服务器——除非我知道我已经准备好了

简而言之:

有保证的消息传递确认被证明是不可能的,但 TCP在“无限”重试的情况下保证传递和顺序。我对 socket.io 消息不太自信,但它们非常强大且易于使用,所以我只是小心使用它们。

于 2014-06-11T21:22:18.760 回答
0

我使用不同的策略确保交付

  1. 我使用套接字发送数据,包括消息中的随机数,以防止重复的消息错误
  2. 对方发送收到消息的确认或我在 x 秒后重新发送
  3. 我每 30 秒使用一次客户端的 REST 调用来请求服务器发送的所有新消息,以捕获传输过程中丢失的任何消息
于 2021-05-19T11:43:29.270 回答