我用 Yjs 搞了个 P2P 协同方案,直接开源

112 阅读4分钟

谁懂啊!跟同事一起用 Draw.io 画架构图的痛——我刚拖完一个服务器节点,他那边“唰”一下给我删了;等我刷新同步,他又吐槽“你改的箭头怎么没了”。单机版 Draw.io 的协作体验,简直像隔着两层口罩打电话,低效又闹心。

直到我挖到 Yjs 这个宝藏(就是靠 CRDT 算法把协同冲突“自动掰直”的神器),突然灵光一闪:能不能把它和 Draw.io 的“心脏”mxGraph 绑在一起?折腾几周后,还真成了!这就是开源项目 y-mxgraph——让 Draw.io 秒变“实时组队绘图神器”,关键还不用搭复杂服务器。

先聊痛点:3 个真实场景,你肯定遇过

1. “异地同步像传文件”?不存在的

以前跟远程同事协作,得反复导出 XML、发微信、提醒“记得覆盖最新版”,改个 3 版文件就乱成一锅粥。现在打开同一个 P2P 房间,你拖图形、我改颜色,屏幕实时同步,延迟低到以为在共用一台电脑。

2. “两人改同一处必冲突”?自动化解了

不用再争“谁先保存谁有理”——Yjs 的 CRDT 算法会偷偷处理冲突:比如你改了图形文本,他调整了图形位置,系统会自动把两处修改“拼”起来,既不丢你的字,也不删他的布局。

3. “搭服务器太麻烦”?P2P 直接连

不想花钱租服务器,又怕公网数据不安全?y-mxgraph 支持 Yjs 的 webrtc 插件,靠公共信令服务器“牵线”,多端直接点对点连接,相当于“绘图版微信视频通话”,数据不经过第三方服务器。

核心逻辑:3 步让 Draw.io“学会协同”

y-mxgraph 没重复造轮子,而是当起了 Yjs 和 Draw.io 的“翻译官”,核心操作简单到离谱:

第一步:给 Draw.io 的 XML“办个 Yjs 身份证”

Draw.io 用 XML 存绘图数据(比如 <mxGraphModel> 标签),y-mxgraph 写了两个“转换器”:

  • xml2doc():把 Draw.io 的 XML,转成 Yjs 能看懂的“Y.Doc 文档”
  • doc2xml():把 Yjs 处理完的文档,转回 Draw.io 能加载的 XML

就像把“中文合同”翻译成“英文版本”,让两个工具顺畅沟通。

第二步:把编辑器和 Yjs“焊死”

调用一句 bindDrawioFile(),就能让 Draw.io 和 Y.Doc“双向奔赴”:

  • 本地操作同步:你在 Draw.io 拖图形、删箭头、改样式,都会自动变成 Yjs 的“变更补丁”
  • 远端操作同步:别人在远端改的内容,Yjs 会自动把“补丁”贴到你的 Draw.io 上,界面实时刷新,不用手动点同步

第三步:开个 P2P 房间,喊同事“组队”

不用搭后端,几行代码就能创建协作房间:

// 1. 新建 Yjs 文档
const doc = new Y.Doc();
// 2. 初始化 P2P 连接(用公共信令服务器牵线)
const provider = new WebrtcProvider('咱们的架构图房间', doc, {
  signaling: ['wss://signaling.yjs.dev'] // 免费可用,也能换自己的信令服务器
});
// 3. 绑定 Draw.io 与 Yjs,搞定!
App.main((app) => {
  bindDrawioFile(app.currentFile, { 
    doc, 
    awareness: provider.awareness // 支持协作光标显示
  });
});

复制这段代码跑起来,把链接发给同事,打开就能实时一起画——比拉腾讯会议共享屏幕还方便。

不止 P2P!这方案还能“举一反三”

要是你需要更灵活的协作方式,y-mxgraph 也能接 Yjs 生态的其他工具:

  • 企业内部协同:换 y-websocket 连自己的服务器,数据更可控
  • 断网不丢数据:加 y-indexeddb,把内容存在浏览器本地,重连后自动同步
  • 增强单机体验:不用任何 Provider,光靠 Yjs 的历史记录功能,就能让 Draw.io 的 Undo/Redo 步数翻倍

简单说,Yjs 生态有的能力,它基本都能“蹭”上。

5 分钟上手:本地跑通 Demo

1. 环境准备

  • Node.js 20+
  • pnpm 10+(npm 也能凑活)

2. 操作步骤

# 1. 克隆仓库
git clone https://github.com/mizuka-wu/y-mxgraph.git
cd y-mxgraph

# 2. 安装依赖
pnpm install

# 3. 启动开发服务器
pnpm dev

打开 http://localhost:5173/y-mxgraph/,再开一个浏览器窗口,两个窗口一起拖图形——看!实时同步生效了。

3. 部署到网上

想让同事直接用?推代码到 GitHub 就行:项目内置了 GitHub Actions(pages.yml),会自动构建并部署 Demo 到 GitHub Pages,不用自己买服务器。

最后:求“队友”一起完善!

目前项目刚跑通核心功能,比如“协作光标显示”还能优化,“多页面协同”的细节也能打磨。如果你也被 Draw.io 协作坑过,或者对 CRDT 协同感兴趣,欢迎来 GitHub 找我:

👉 项目地址github.com/mizuka-wu/y…

不管是提 Bug、加功能,还是单纯来吐槽“以前协作多难受”,都欢迎!毕竟好工具,都是大家一起“用着用着”就完善了~