实时协作编辑 - 它是如何工作的?

时间:2011-02-23 03:29:59

标签: javascript ajax

我正在编写一个应用程序,其中我希望为文档提供近乎实时的协作编辑功能(非常类似于Google文档样式编辑)。

我知道如何跟踪光标位置,这很简单。只需使用可存储在数据库中的当前用户ID,文件名,行号和行号来轮询服务器半秒或秒,并且此轮询请求的返回值是其他用户游标的位置。

我不知道该怎么做是以这样的方式更新文档:它不会将光标关闭并强制完全重新加载,因为这对我的目的而言会慢得多。

这实际上只能在Google Chrome中使用,最好是Firefox。我不需要支持任何其他浏览器。

7 个答案:

答案 0 :(得分:45)

用于合并来自多个对等方的协作编辑的幕后使用的算法称为operational transformation。尽管如此,实施并非易事。

有关有用的链接,另请参阅this question

答案 1 :(得分:13)

你不一定需要xmpp或wave。关于一个名为infinote的开源实现的大部分工作已经完成了jinfinote(https://github.com/sveith/jinfinote)。 Jinfinote最近也被移植到python(https://github.com/phrearch/py-infinote)来集中处理并发和文档状态。我目前在hwios项目(https://github.com/phrearch/hwios)中使用它,它依赖于websockets和json传输。您不希望真正想要对这些类型的应用程序使用轮询。此外,xmpp似乎不必要地使事情变得复杂。

答案 2 :(得分:12)

实时协作编辑需要一些有效的方法。这里的大多数其他答案只关注问题的一个方面;即分布式状态(又名共享可变状态)。操作转换(OT),无冲突复制数据类型(CRDT),差异同步和其他相关技术都是实现近实时分布式状态的方法。大多数注重最终的一致性,这允许每个参与者状态的临时分歧,但保证每个参与者状态最终会在编辑停止时收敛。其他答案提到了这些技术的几种实现方式。

但是,一旦您拥有共享可变状态,您需要其他几个功能来提供合理的用户体验。这些附加概念的示例包括:

  • 身份:与您合作的人是谁。
  • 在线状态:现在正在“编辑”这个人。
  • 通讯:允许用户协调操作的聊天,音频,视频等
  • 协作提示:指示其他参与者正在做什么和/或即将做什么的功能。

共享游标和选择是协作提示(a.k.a Collaboration Awareness)的示例。它们可以帮助用户了解其他参与者的意图以及可能的下一步行动。最初的海报部分询问了共享可变状态和协作提示之间的相互作用。这很重要,因为通常通过文档内的位置来描述文档中的光标或选择的位置。问题是游标的位置(例如)取决于文档的上下文。当我说我的光标位于索引37时,这意味着我正在查看的文档中的字符37。由于您的编辑或其他用户的编辑,您现在可能拥有的文档可能与我的文档不同,因此文档中的索引37可能不正确。

因此,用于分发游标位置的机制必须以某种方式集成到或至少知道系统的机制,该机制提供对共享可变状态的并发控制。今天的挑战之一是虽然有许多OT / CRDT,双向消息传递,聊天和其他库,但它们是未集成的独立解决方案。这使得构建提供良好用户体验的最终用户系统变得困难,并且经常导致开发人员难以理解的技术挑战。

最终,要实现有效的实时协作编辑系统,您需要考虑所有这些方面;我们甚至没有讨论历史,授权,应用程序级别的冲突解决方案以及许多其他方面。您必须以对您的用例有意义的方式构建或查找支持这些概念的技术。然后你必须整合它们。

好消息是支持协作编辑的应用程序正变得越来越流行。支持构建它们的技术正在成熟,每个月都有新的技术可用。 Firebase是最早尝试将其中许多概念包装成易于使用的API的解决方案之一。新人Convergence(完全披露,我是Convergence Labs的创始人),提供了一个支持大多数协作编辑方面的一体化API,可以显着减少时间,成本和复杂性建立实时协作编辑应用程序。

答案 3 :(得分:6)

在提出这个问题并进行更仔细的搜索后,我认为最好的独立应用程序将是Etherpad,它作为JS浏览器应用运行并在服务器端使用Node.js。这背后的技术称为operational transformation

Etherpad最初是一款非常重量级的应用程序,被Google收购并整合到Google Wave中,但失败了。该代码作为开源发布,该技术在Javascript for Etherpad Lite中重写,现在更名为“Etherpad”。一些Etherpad技术可能也被整合到Google Docs中。

自Etherpad以来,该技术已有各种版本,特别是一些允许将其直接集成到您的网络应用程序中的Javascript库:

我是meteor-sharejs软件包的维护者,用于将实时编辑器直接添加到Meteor应用程序中,恕我直言是两全其美的:)

答案 4 :(得分:3)

正如Gintautas指出的那样,这是由运营转型完成的。据我了解,此功能的大部分研究和开发是作为现已解散的Google Wave项目的一部分完成的,被称​​为Wave Protocol。幸运的是,Google Wave是开源的,因此您可以在http://code.google.com/p/wave-protocol/

获得一些优秀的代码示例

答案 5 :(得分:2)

Google Docs团队针对实时协作的工作方式进行了一些案例研究,但我找不到博客条目。

维基百科页面上有一些不错的东西: http://en.wikipedia.org/wiki/Collaborative_real-time_editor

答案 6 :(得分:0)

我最近发布了一个存储库,其中包含了您正在尝试实现的实际示例:

https://quill-sharedb-cursors.herokuapp.com

它基于ShareDB(OT)作为前端和前端的Quill富文本编辑器。

基本上只需用some more code to draw the cursors连接所有这些东西。代码应该很容易理解并复制到任何特定的解决方案。

希望它有助于努力。