[]
SpreadJS 协同采用 OT(操作转换)方法,基于 js-collaboration-ot 中概述的约束实现了符合 SpreadJS 协同要求的 OT_Type,并包含额外功能。代码库分为前端和后端两个包:
spread-sheets-collaboration-client:处理客户端功能。
spread-sheets-collaboration:处理服务器端功能。
仅提供 npm 安装,有两个可用包:
npm install @grapecity-software/spread-sheets-collaboration-client
npm install @grapecity-software/spread-sheets-collaborationspread-sheets-collaboration-client 包提供以下功能:
实现 OT_Type
提供工作簿与文档的简单绑定
过滤不需要协同的操作
绑定 SpreadJS 与存在状态相关的功能
spread-sheets-collaboration-client 包提供了专为 SpreadJS 协同定制的 OT_Type。用户可以通过引用直接使用它。
注册类型:
import * as OT from "@grapecity-software/js-collaboration-ot-client";
import {type} from '@grapecity-software/spread-sheets-collaboration-client';
OT.TypesManager.register(type);创建带类型的文档:
import {type} from '@grapecity-software/spread-sheets-collaboration-client';
try {
doc.create('Hello', type.uri, {}).then(() => {
console.log('文档创建成功:', doc.data); // "Hello"
});
} catch (err) {
console.error('创建失败:', err);
}为工作簿注册类型:
import {type} from '@grapecity-software/spread-sheets-collaboration-client';
const workbook = new GC.Spread.Sheets.Workbook('ss');
workbook.collaboration.registerCollaborationType(type);工作簿目前提供了几个用于快照和变更集的 API,详情见 协同插件-快照与变更集。
文档也提供了监听和提交操作的功能,详情见 SharedDoc 类。
从工作簿的角度看,一个变更集相当于文档中的一个操作,因为文档不关心具体的操作。
在协同中,工作簿作为操作的生产者和消费者,而文档作为可以提交和接收操作的实体。因此,需要将工作簿和文档绑定在一起。
主动绑定
核心思想与 SharedDoc 类-与 ui 组件集成 一致。
// 订阅文档
doc.subscribe().then(async () => {
// 如果没有类型,说明文档尚未创建;继续创建它
if (!doc.type) {
// 创建文档
await doc.create(workbook.collaboration.toSnapshot()/* 默认快照 */, type.uri, {});
console.log('创建成功:', doc.data);
}
// 基于快照刷新当前工作簿
workbook.collaboration.fromSnapshot(doc.data);
// 绑定工作簿的操作事件;当工作簿有操作时,将其提交给文档
workbook.collaboration.onChangeSet(async (changeSet: IChangeSet) => {
await doc.submitOp(changeSet, { source: doc.connection.id });
});
// 监听文档接收到的操作
doc.on('op', (changeSet: IChangeSet, source: unknown) => {
// 如果操作是由自己发送的,则不需要处理
if (source === doc.connection.id) {
return;
}
// 让工作簿应用生成的操作
workbook.collaboration.applyChangeSet(changeSet);
});
})默认绑定方法
spread-sheets-collaboration-client 包提供了一个简单的 bind 方法来绑定文档和工作簿,不过它不会创建文档。
import { bind } from '@grapecity-software/spread-sheets-collaboration-client';
// 请求文档
doc.fetch().then(async ()=>{
// 如果不存在,创建它
if(!doc.type){
await doc.create(workbook.collaboration.toSnapshot(), type.uri, {});
bind(workbook, doc);
}else{
bind(workbook, doc);
}
});操作介绍:协同插件-快照与变更集 - 操作(Op)
由于操作描述了对模型的所有修改,如果用户希望某些数据变更(例如缩放变更、活动工作表变更)不参与协同,有两种方法:
如果希望其他客户端和服务器不应用特定操作,在提交给文档之前按操作类型过滤:
workbook.collaboration.onChangeSet((changeSet: IChangeSet) => {
const submitOps = changeSet.ops.filter(op => op.type !== OpType.updateZoom);
if (!submitOps || submitOps.length === 0) {
return;
}
doc.submitOp({ ...changeSet, ops: submitOps }, { source: doc.connection.id });
});如果希望其他客户端不应用某个操作,但仍允许服务器应用它,在工作簿应用操作之前按操作类型过滤:
doc.on('op', (changeSet: IChangeSet, source: unknown) => {
if (source === doc.connection.id) {
return;
}
const needApplyOps = changeSet.ops.filter(op => op.type !== OpType.setActiveSheetId);
if (!needApplyOps || needApplyOps.length === 0) {
return;
};
});bind 方法目前包含内置过滤器,具体如下:
不提交:OpType.updateZoom 和 OpType.updateTopLeftPosition。
不应用:OpType.setActiveSheetId、OpType.setTabSelected 和 OpType.setStartSheetIndex。
如果不希望使用这些过滤器,请实现自己的绑定方法。
提供 bindPresence 方法以在 SpreadJS 中实现存在状态功能。详情见 活动状态
spread-sheets-collaboration 包提供 OT 类型。
spread-sheets-collaboration 包提供了专为 SpreadJS 协同定制的 OT_Type。用户可以通过引用直接使用它。
注册类型:
import * as OT from '@grapecity-software/js-collaboration-ot';
import { type } from '@grapecity-software/spread-sheets-collaboration';
OT.TypesManager.register(type);关于其余服务器使用方法以及如何与其他协同工作流对齐,请参考 服务器初始化完整示例。
本章节包是对底层 OT 类型 接口的 SpreadJS 专属实现。如需了解 OT 类型的通用接口(uri / create / transform / apply)与自定义 OT 类型的方法,参见 底层协同框架 中的 OT 类型。