https://www.toutiao.com/article/7251914839722295864
今天给大家带来的主题是 DerbyJS,即让开发者轻松编写在 Node.js 和浏览器中运行的实时协作应用框架。话不多说,直接进入正题!
1.强大的实时协作 ShareDB
ShareDB 是一个基于 JSON 文档操作转换 (Operational Transformation,OT) 的实时数据库后端。
Realtime database backend based on Operational Transformation (OT)
ShareDB 具有以下特点:
实时同步任何 JSON 文档
并发多用户协作
具有异步最终一致性的同步编辑 API
实时查询订阅
与任何数据库简单集成
通过发布/订阅集成进行水平扩展
从文档和操作中选择所需字段的投影
用于实现访问控制和自定义扩展的中间件
非常适合在浏览器或服务器上使用
重新连接时离线更改同步
用于单元测试的数据库和发布/订阅的内存中实现
访问历史文档版本、实时用户状态同步
目前 ShareDB 在 Github 上开源,有超过 5.7k 的 star、0.5k 的 fork、0.8k 的项目依赖量,是一个值得关注的开源项目。
2.强大的 Racer
Racer 是 Node.js 的实时模型同步引擎。 通过利用 ShareDB,多个用户可以通过操作转换(一种实时且与离线客户端一起工作的复杂冲突解决算法)与相同的数据进行实时交互。
ShareDB 还支持跨多个服务器的 PubSub 以进行水平扩展。 客户端可以通过查询和特定文档来表达数据订阅和获取,因此不同的客户端可以订阅不同的重叠数据集。 在这个复杂的后端之上,Racer 提供了一个简单的模型和事件接口来编写应用程序逻辑。
Racer 的典型特征可以概括为以下几个点:
实时更新:模型方法自动在浏览器客户端和 Node.js 服务器之间实时传播更改,开发者还可以使用 racer-browserchannel 适配器来实时连接浏览器。
实时查询订阅:客户端可以订阅与当前会话相关的有限信息集。 支持文档订阅和实时查询订阅,已支持任意 Mongo 查询。
冲突解决:利用 ShareDB 的 JSON 操作转换算法,Racer 将发出事件,使冲突的客户端状态达到最终的一致性。 除了同步 API 之外,模型方法还具有用于在服务器响应后处理已解析状态的回调。
立即交互:模型方法似乎立即生效。 同时,Racer 会将更新发送到服务器并检查是否存在冲突。 如果更新成功,它们将被存储并广播给其他客户端。
离线支持 : 由于模型方法会立即应用,因此客户可以继续离线工作。 对本地客户端或全局状态的任何更改都会在重新连接时自动同步。
统一的服务器和客户端接口 : 可以在服务器上使用相同的模型接口进行初始页面渲染,并在客户端上进行用户交互。 Racer 支持打包在服务器上创建的模型,并在浏览器中以相同状态重新初始化。
持久存储 : Racer 使用 ShareDB 保存所有数据操作的日志,将操作发布到多个前端服务器,并自动持久保存文档。 它目前支持 MongoDB,并且可以轻松调整以支持其他文档存储。
访问控制 :Racer 将具有访问控制 hooks,以保护文档免遭恶意读写。
Solr 查询 :Solr 适配器将支持随着数据变化更新 Solr 索引以及实时更新搜索结果的查询。
目前 Racer 在 Github 上已经开源,有超过 1.2k 的 star、是一个值得关注的前端项目。
3. Derby 站在巨人的肩膀上
Derby MVC 框架可以让开发者轻松编写在 Node.js 和浏览器中运行的实时协作应用程序。
Derby MVC 借助于 Racer 的强大数据同步引擎,可自动在浏览器、服务器和数据库之间同步数据。 模型订阅特定对象的更改,从而无需定义通道即可对数据传播进行精细控制。同时, Racer 支持离线使用和开箱即用的冲突解决,这大大简化了多用户应用程序的编写。
Derby 应用程序会立即加载,并且可以被搜索引擎索引,因为相同的模板在服务器和客户端上渲染。 此外,模板定义了绑定,当模型发生变化时,它会立即更新视图,反之亦然。 Derby 使得编写的程序加载速度像搜索引擎一样快、像文档编辑器一样交互并且使得开发离线工作的应用程序变得很简单。
目前 Derby MVC 在 Github 上通过 MIT 协议开源,有超过 4.7k 的 star、0.3k 的 fork,是一个值得关注的前端开源项目。
4.Derby 到底有什么魔力
本质上,Derby MVC 通过 ShareDB 对 JSON 和文本的操作转换(Operational Transformation,OT)提供支持的自动冲突解决方案,轻松跨客户端和服务器同步数据。
支持服务端渲染
Derby 模板可以在浏览器和服务器上渲染。 在浏览器中,DerbyJS 使用快速、本机 DOM 方法进行渲染。
在服务器上,Derby MVC 也不需要 DOM 或虚拟 DOM 实现 ,相同的模板返回 HTML。HTML 渲染意味着更快的页面加载、完整的搜索引擎支持以及对所有类型的 HTML 输出(例如:电子邮件)使用相同模板的能力。
Render anywhere!
<div style="text-align: right">
{{each data.bars as #bar}}
<div style="width: {{#bar.value}}px; border-bottom: 4px solid {{data.color}};">
{{Math.floor(#bar.value)}}
</div>
{{/each}}
</div>
组件和数据绑定
使用设计者友好的 HTML 模板将代码组织成组件。 轻松指定视图和模型之间的实时绑定,以便当数据更改时,视图立即更新。
支持模块化
DerbyJS 由多个标准 Node.js 模块组成。将自己的代码、社区模块和 DerbyJS 功能与 npm 和 browserify 等标准工具混合并匹配。
同时 DerbyJS 还有丰富的社区,以及较高的社区活跃度。
5.如何使用 Derby
5.1 安装
为了编写第一个 DerbyJS 应用程序,开发者需要首先安装 Node.js 和 MongoDB。
虽然 DerbyJS 是为支持任何数据库而编写的,但 MongoDB 适配器是最完整的。
5.2 运行官方示例
derby-examples 存储库中有几个示例,开发者可以克隆存储库并安装:
git clone https://github.com/derbyjs/derby-examples.git
cd derby-examples
npm install
开发者也可以从各自的目录运行每个示例:
cd ~/derby-examples/directory
node server.js
用 CoffeeScript 编写的示例旨在通过 Coffee 命令运行:
npm install -g coffeescript
cd ~/derby-examples/sink
coffee server.coffee
5.3 Derby 的 hello world 示例
下面给出 Derby 官方的 hello world 示例。比如下面是 index.html 的文本内容:
<Body:>
<!--Templates define both HTML and model-view bindings-->
Holler: <input value="{{hello.message}}">
<h2>{{hello.message}}</h2>
index.js 的文本内容如下:
var app = (module.exports = require("derby").createApp("hello", __filename));
app.loadViews(__dirname);
// 路由在客户端和服务器上渲染
app.get("/", function (page, model) {
// 订阅指定要同步的数据
var message = model.at("hello.message");
message.subscribe(function (err) {
if (err) return next(err);
message.createNull("");
page.render();
});
});
server.js 的文件内容如下:
require("derby-starter").run(__dirname, { port: 8005 });
关于 Derby 的更多用法示例本文不再过多展开,可以参考文末资料自行阅读。
6.本文总结
本文主要和大家介绍 DerbyJS,即让开发者轻松编写在 Node.js 和浏览器中运行的实时协作应用框架。相信通过本文的阅读,大家对 DerbyJS 会有一个初步的了解。
因为篇幅有限,关于 DerbyJS 的更多用法和特性文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏,您的支持是我不断创作的动力。
参考资料
https://github.com/derbyjs/derby/tree/ba8e2d9c0cf41722c42fa8ddda7a5b6fc73fb7
https://derbyjs.com/docs/derby-0.10
https://github.com/share/sharedb
https://github.com/derbyjs/racer
https://github.com/derbyjs/derby-examples/blob/master/hello/index.js