【问题标题】:What is a good practice to have an invariant ordering in a real-time commenting system?在实时评论系统中具有不变排序的好习惯是什么?
【发布时间】:2014-11-05 01:58:13
【问题描述】:

让我们假设这个用例:

Bob 想要评论博客的帖子。
他在写:“我是第一个评论的!”。

几毫秒后,爱丽丝发表了这条评论:“我是第二个!”。

假设每个发布的评论都通过某种 WebSockets 显示给其他用户,而不刷新整个页面。
并假设 cmets 列表应按评论的日期升序排列。

鲍勃应该看到这个:

  • 鲍勃:我是第一个
  • 爱丽丝:我是第二个

现在假设评论的发布是一个异步过程,这意味着一旦用户点击“发送”,列表就会更新其条目,而不是等待服务器处理:

如果 Bob 的评论在 Alice 的评论之前发送,但在 Alice 的评论之后被服务器处理(存储)了怎么办?

真正的显示(但在 Bob 的屏幕上无效)是:

  • 爱丽丝:我是第二个
  • 鲍勃:我是第一个

但鲍勃会看到:

  • 鲍勃:我是第一个
  • 爱丽丝:我是第二个

=> 这没有意义...爱丽丝在鲍勃之后立即在她的键盘上键入。

整个页面的简单刷新将显示:

  • 爱丽丝:我是第二个
  • 鲍勃:我是第一个

让鲍勃感到困惑!

如果服务器进程是同步的,则不会发生这种情况,这意味着列表将在服务器提交评论后有效显示。
=> Bob 会看到 Alice 的评论出现在他之前,这是一致的。

这种情况下如何处理异步?

【问题讨论】:

  • 不要通过id 而是通过create_date 列订购cmets,服务器和客户端都是明智的。当通过 websocket(或任何异步连接)的新评论到达时,使用 create_date 将其插入 cmets。
  • 当然可以,但我认为您没有很好地解释这个问题。 Bob 的评论不会重新发送给 Bob... => 所以 Bob 仍然会在顶部看到他的评论(直到他刷新整个页面),因为客户端的 create_date 总是在 Alice 的前面;即使爱丽丝之前计算过。
  • 不,他不会因为服务器将 alices 评论转发给 bob,然后将其插入到 bob 评论之后,因为它的时间戳比 bob 更新。或者您只需将带有评论的客户端创建时间戳发送到服务器,检查其是否现实(以防止人们在几周后发表评论并将时间戳更改为第一个),然后使用客户端时间戳或生成一个新的服务器端.因此,如果它们有效,您实际上是在使用客户端时间戳。
  • 我指出 cmets 由 create-date asc 显示,而不是 desc。所以 Bob 的评论在他的客户端的创建日期,总是在没有完全刷新的任何其他 cmets 之前。
  • 好的,我已经编辑了我的评论并将“之前”替换为“之后”,因为顺序没有区别。

标签: javascript asynchronous architecture websocket real-time


【解决方案1】:

如果 Bob 的评论还不存在,Alice 怎么知道她是第二个。

对于这个特定的示例,如果订单与此事无关,我会将它们置于处理订单或到达订单中。这就是大多数博客和您可以发表评论的地方的做法。其实经常看到前两三个cmet自称是第一个:D

现在,如果订单确实相关,您可以使用optimistic concurrency 方法。基本上,每次生成页面时,都会添加一个标识 cmets 状态的哈希;发送评论时,您也发送该哈希,并且如果页面在用户获取页面和插入评论之间没有更改,那么一切都很好,您可以使用新评论和新哈希再次生成页面;否则,它将返回一个“错误”,刷新 cmets 并警告用户页面已更改,他可能需要在撰写评论之前查看页面和当前 cmets。

更新:

如果您想要更可靠/异步的方法,您可以使用vector clocks。但是聊天似乎有点矫枉过正:),可能按到达顺序显示它们就足够了。

【讨论】:

  • 您的乐观解决方案将暗示同步调用而不是完全异步:在发送评论之前查询当前哈希。
  • "我会将它们按处理顺序排列" => 需要同步调用...为了等待服务器响应。我所说的完全异步是:Bob 单击按钮 => 立即将他的评论插入到他的屏幕中。因此无法获得“处理”日期。
  • 我想要一个与聊天完全相同的行为。
  • 我用分布式时钟的链接更新了我的回复。
  • 如果订单很重要并且在其他地方控制,您不能立即添加消息。
猜你喜欢
  • 2015-03-03
  • 2017-11-23
  • 2013-03-10
  • 2018-04-07
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
  • 2017-04-03
  • 1970-01-01
相关资源
最近更新 更多