实时协作:体系结构

本期的目标是制定技术架构,以在WP中实现实时协作管理员管理员 (和超级管理员)(帖子和网站编辑)。请参见以下内容引导桩有关项目范围和功能的更多信息。

正如帖子上所述,我们希望启用不同的使用卡,但所有这些都归结为以下两个基本方面:

  • 需要在连接到同一WP-Admin的用户之间共享和同步数据。
  • 如果网络网络 (与网站、博客相比)断开连接后,数据将在本地持久化并同步回恢复网络的服务器。

除此之外,我想为我们试图概念化的技术解决方案添加另一个指导原则:

理想情况下,开发人员在用户界面用户界面 用户界面WP-Admin/editors不必考虑数据是否是本地/远程/同步/合并的……开发人员声明他们的“数据需求”,这些需求通过一个单独的自动化层来满足。 

这一原则之所以重要,有多种原因:

  • 它使开发人员不必考虑为他们添加的每个新特性和UI片段进行同步和协作。默认情况下,其他数据将是协作的,并且是离线的。
  • 确保现有面向公众的API的向后兼容性,以访问和操作WordPress数据也很重要。

这也是我们在最初开发@文字新闻/数据包来满足本地和远程数据需求。

当前架构

以下模式表示数据如何在站点和后期编辑器代码库中流动。

该体系结构分为两部分:

  • UI层:开发人员通常会编写组件,使用选择器声明其数据需求(如上例中的“getEntityRecord”选择器,并自动收到数据更改的通知。开发人员还可以使用操作来执行更改。(编辑帖子,保存帖子…)。
  • 这个核心核心 Core是运行WordPress所需的一组软件。核心开发团队构建WordPress。数据层:负责解决数据需求,从服务器或本地检索数据,缓存数据(如果需要),并通知消费者(UI层)任何更改。

建议书

因此,这里的目标是在远程对等方(协作者)之间引入数据同步,同时在本地持久化数据,而不影响UI层。为此,我们可以介绍同步引擎.

现有技术:看看这个资源如果您想阅读更多关于SPA和现有技术中脱机同步引擎的信息(Figma、Linear…)

为了更好地理解这种同步引擎的工作原理,我们来看一个小示例。首先要注意的是,所有呈现/共享/持久化的数据都可以表示为文档/对象因此,同步引擎的作用是在本地获取/检索/持久化这些对象发生的任何更改。

  • 用户(UI组件)通过调用`getEntityRecord来请求id为1的帖子`美国石油学会美国石油学会 API或应用程序编程接口是一种软件中介,允许程序相互交互并以有限的、明确定义的方式共享数据。我们的核心数据包。 
  • 在内部,核心数据要求同步引擎引导数据库一份文件类型帖子及其标识符为1。
  • 首先,同步引擎在内存中创建一个“文档”,表示真相的来源。
  • 同步引擎尝试从本地数据库加载该文档。如果找不到,它会创建一个空数据库,以保留该特定文档将来的任何更改。
  • 然后,同步引擎执行我们称之为握手当它连接到远程对等方时,所有处理同一文档的协作者(类型post,标识符1)并将本地副本与远程对等方副本合并。
  • 同步引擎还异步触发取来调用从WordPress后端检索文档,并刷新本地副本,如果没有连接本地副本或远程对等点,则对其进行初始化。
  • 最后,发生在本地文档上的任何更改,无论更改的来源是什么(用户触发的更改、从本地数据库加载的更改、由远程对等方触发的更改)都会触发相同的更改更改处理程序在核心数据包中。
  • 调用更改处理程序后,UI组件将收到通知(重新渲染)。

Yjs简介

我们可以将建议的同步引擎的实现分为以下步骤:

  1. 介绍可观察的文档对象:内存中的文档对象,带有用于进行更新和订阅更改的API。
  2. 支持将多个来源的更改合并到可观察的文档中。请注意,基本上有两种同步更改的方法:冲突冲突 当修补程序更改在创建修补程序后修改的代码时,会发生冲突。考虑这些补丁不新鲜的,并将需要刷新或冲突需要已解决.-自由复制数据类型(CRDT公司)和运营转型(OT)之前的研究表明,OT过于复杂,无法在现有架构上实现。 
  3. 将文档更改加载并持久化到本地数据库。
  4. 连接到同一WordPress管理员的所有用户之间的通信层。  

幸运的是,有一些开源开放源代码 开放源代码是指原始源代码可以免费获得,并且可以重新发布和修改的软件。开源**必须**通过许可模式交付,请参阅GPL。这些解决方案可以帮助我们实现所建议的同步引擎并满足大多数这些需求。在之前的探索中使用的最有希望的方法是Yjs公司.

Yjs是CRDT的一个实现。您可以将其视为一种数据结构,可以用来表示正在同步的对象。一旦您使用了这种特殊表示法,Yjs就提供了适配器来满足上述所有需求:观察更改、合并来自不同来源的更改、持久化到本地数据库并可能与其他对等方通信。

问答

虽然这个库解决了我们的大多数需求,但探索表明,问题在于细节。编写同步引擎是一个具有挑战性的项目,有很多问题需要解决。

添加的可观察对象以及从常规对象到等效CRDT格式的来回转换对性能的影响如何?

同步引擎很可能会对性能产生较小的影响,即使是对本地更改,但这种影响是否会成为拦截器拦截器 一个严重到阻止发布的错误。或者没有。我们确实有适当的工具(性能指标),在一切就绪后帮助评估问题。

Yjs默认允许使用WebRTC或WebSockets在对等端之间同步文档,哪个通信层最适合WordPress?

正如引导帖子中提到的,这是我们面临的最大挑战之一PHP程序PHP程序 WordPress主要使用的web脚本语言。WordPress需要PHP 5.6.20或更高版本托管提供商不支持使用web套接字进行restful通信。 

这意味着我们需要一个替代通信层,默认情况下可以与任何WordPress安装一起工作,同时允许通信层被插件/主机替换。

我们可以使用WebRTC作为默认的通信层吗?因为它是P2P,并且应该适用于所有WordPress安装?

虽然WebRTC确实是P2P,但大多数现有的WebRTC实现,包括默认的Yjs WebRTC适配器,都依赖于集中式信号服务器。这是一个非常轻的服务器,用于执行握手(让对等方发现彼此),通常依赖于web套接字。

由于我们不能依赖网络套接字,我们可以探索三种可能性:

  • 构建一个公共信号服务器(例如,在.org基础设施上)。
  • 使用长轮询而不是web-sockets(在所有WordPress实例中都支持)和公共stun服务器(现有的公共stun服务器和.org基础设施也可以根据需要提供一个)来实现WebRTC信令。这还包括提供一个自定义的Yjs适配器来支持基于轮询的信令服务器。
  • 默认情况下避免使用WebRTC,并使用长轮询来执行握手和数据更改。在这种情况下,不需要公共服务器,但性能可能会受到影响。

作为项目的一部分,我们还应该考虑什么

  • 性能影响。
  • 共享文档的内存占用。
  • 本地数据库的存储占用空间。(yjs通过一些优化来存储更改的历史记录)。
  • 安全:防止在没有必要权限的情况下访问对等方。
  • 撤消/重做。

参与进来!

我们刚刚开始这个旅程,有一些开放性问题,如果你对挑战感兴趣或想对项目留下任何反馈,请报到.

#古腾堡#第三阶段