让我们假设这个用例:
鲍勃想评论一篇博客文章
他写道:"我是第一个发表评论的人!"。
几毫秒后,爱丽丝发表了这样的评论:"我是第二个!"。
假设每个发布的评论都通过某种WebSocket显示给其他用户,而不刷新整个页面
假设评论列表应该按照评论的日期asc排序。
Bob应该看到这个:
- 鲍勃:我是第一个
- 爱丽丝:我是第二个
现在假设发布评论是一个异步过程,这意味着只要用户单击"发送",列表就会更新其条目,而不等待服务器处理:
如果Bob的评论,尽管是在Alice的评论之前发送的,但被服务器处理(存储)在Alice评论之后呢?
真正的显示(但在Bob的屏幕上无效)是:
- 爱丽丝:我是第二个
- 鲍勃:我是第一个
但是Bob会看到:
- 鲍勃:我是第一个
- 爱丽丝:我是第二个
=>这没有道理。。。爱丽丝紧跟着鲍勃在键盘上打字。
整个页面的简单刷新将显示:
- 爱丽丝:我是第二个
- 鲍勃:我是第一个
鲍勃很困惑!
如果服务器进程是同步的,则不会发生这种情况,这意味着在服务器提交注释后,列表将有效地显示出来
=>鲍勃会看到爱丽丝的评论出现在他的评论之前,这是一致的。
在这种情况下如何处理异步?
如果Bob的评论还不存在,Alice怎么会知道自己是第二个呢。
对于这个特定的例子,如果订单与此事并不真正相关,我会将它们放入处理订单或到达订单中。大多数博客和你可以发表评论的地方都是这样做的。事实上,通常会看到前两三条评论声称是第一条:D
现在,如果顺序真的相关,您可以使用乐观并发方法。基本上,每次生成页面时,都会添加一个散列来标识注释的状态;当发送评论时,你也会发送该散列,如果页面在用户获取页面和插入评论之间没有变化,那就好了,你用新的评论和新的散列再次生成页面;否则,它将返回一个"错误",刷新评论,并警告用户页面已更改,他可能需要在撰写评论之前查看页面和当前评论。
更新:
如果您想要更可靠/异步的方法,可以使用矢量时钟。但聊天似乎有点过头了:),可能按照到达顺序显示就足够了。