OpenPencil 实时协作指南:基于 WebRTC + CRDT 的无服务器多人协同编辑 前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载OpenPencil 是一款 AI-native 设计编辑器开源 Figma 替代品其协作能力完全内置于产品本身通过 P2P WebRTC 直连、CRDT 自动合并任何人无需账号即可实时共同编辑同一份设计文档。本文以官方文档 collaboration.md 为主体结合仓库源码src/app/collab、tests/app/collab讲解房间的分享与加入、同步范围、跟随模式以及底层 P2P 与 CRDT 原理读完后你可以立刻上手多人协同并理解其数据如何在不经过中心服务器的前提下保持各端一致。核心概念房间Room在 OpenPencil 中协作以“房间”为基本单位。一个房间对应一份被共享的设计文档分享Share只有分享动作才会把当前文档放入房间。被你分享的那个标签页会成为房间的标签页并始终与该文件绑定。加入Join任何拿到链接的人都可以加入房间无需注册或登录。无服务器房间不存储在服务器上文件实际存在于曾经进入过房间的各设备中见 session.ts 中的本地持久化逻辑。多房间并行每个房间标签页持有独立的连接rooms.ts 中sessions按标签页管理所以你可以同时处于多个房间且都能在后台持续同步。从源码看房间会话RoomSession封装了一个房间在一枚标签页中的全部状态文档、在线成员peers、连接与本地保存副本session.ts。分享一个房间点击右上角的分享按钮点击Share this file链接app.openpencil.dev/share/room-id即被复制把链接发送给协作者即可。对应的前端路由前缀在 route.ts 中定义SHARE_ROUTE_PREFIX /share/房间 URL 即/share/room-id。地址栏会跟随当前激活标签页的房间状态route.ts因此刷新页面或复制地址栏 URL 打开的正是屏幕上那份文档。房间 ID 由 awareness.ts 的generateRoomId()生成基于ROOM_ID_CHARS与ROOM_ID_LENGTH见 constants.ts每次随机抽取字符因此只有拿到链接的人才能加入。加入一个房间直接打开链接或把完整链接甚至只有房间 ID粘贴到分享面板的Join输入框、Home 页的Join room…在电脑上浏览器还会提示Open in desktop app通过openpencil://join链接在桌面版 OpenPencil 中打开该房间。加入行为由 rooms.ts 的joinRoom()实现校验房间 ID 合法性isRoomId、创建独立的新标签页createTab()并在文档到达前先显示加入中的占位页。因此你已打开的文档永远不会被改动。访客名称加入后你会立即获得一个自动生成的名称例如Teal Fox。生成逻辑在 guest-name.ts从 16 个颜色词Amber、Azure、Coral、Cobalt、Copper、Crimson、Indigo、Ivory、Jade、Lilac、Olive、Ruby、Saffron、Scarlet、Teal、Violet与 16 个动物词Badger、Crane、Dolphin、Falcon、Fox、Gecko、Heron、Ibis、Koala、Lynx、Marten、Otter、Panda、Puffin、Raven、Wombat中各随机取一组合而成。你可以在分享面板或设置里改成自己的名字该名字会在所有房间中使用身份信息通过 awareness 广播见 session.ts。等待与离线文件房间文件不在服务器上因此只有当至少一个进过房间的人在线时房间标签页才能打开文档。在此之前它显示“等待中”并解释原因一旦某个持有文件的人加入文档就会立即打开。如果你曾进过这个房间会先从本机副本直接打开快速显示等其他人回来后再同步你的修改本机副本由IndexeddbPersistencey-indexeddb保存键名为op-room-roomIdsession.ts并异步等待其加载完成后才判定“已有文档”。离开房间分享面板中的Leave room结束你在这个房间的参与分享过文档的标签页回到“普通文档”状态加入过房间的标签页保留房间文件作为本地未保存副本可另存若文档从未到达标签页会被关闭rooms.ts。同步范围哪些内容实时同步文档修改所有编辑形状、文本、属性、布局即时同步光标可看到每个协作者指向的位置、名字与颜色选区高亮的选中状态对所有人可见Agent内置 AI 聊天、ACP 与 Pi harness 聊天、以及每个已连接的 MCP 客户端都会以其正在读取或编辑的图层上的光标形式出现——每个带轮廓的标签显示一个星标sparkle和呼号如Fern。聊天流式输出 JSX 时光标会随元素逐个出现并给它们描边。光标与描边使用运行该 Agent 的人的颜色方便区分是谁的 Agent。只共享名称、类型、模型、状态、所在页、位置与被编辑图层绝不共享提示词或回复内容。从实现上看这些同步通过两类机制完成session.ts文档数据写入ydoc.getMap(nodes)图层与ydoc.getMap(images)图片二进制由 Yjs 增量同步存在感presence基于y-protocols/awareness广播用户信息、光标{x, y, pageId, zoom}、选区selection、hasFile是否持有文档等字段session.ts。跟随模式Follow Mode点击顶部栏某协作者的头像即可跟随其视口你的画布会平移、缩放以匹配对方的视野并用对方颜色的边框与一条 “Following …” 提示条标示你正在跟随谁再次点击头像、按Esc、或自己点击/滚动/缩放/切换页面都会停止跟随。跟随 Agent你自己的 AgentAI 聊天、MCP 客户端如 Claude Code 或 Cursor在运行时会被自动跟随确保它们编辑的内容始终在视野内可在 AI 面板顶部的十字准星按钮关闭若在 Agent 工作时停止跟随它会独自工作到结束下一次运行时才会再次被跟随头像上的数字表示该用户运行了几个 Agent悬停可查看每个 Agent 在做什么、在哪一页点击某 Agent 旁的Follow可保持其正在编辑的页面与图层在视野内跟随会持续到 Agent 回复之间并在其离开时停止头像之后的按钮列出房间内所有成员及其 Agent支持键盘操作你自己的头像列出你的 Agent——点击即可重命名——并提供Leave room分享面板同样列出房间成员及其 Agent 的状态与所在页双击自己的 Agent 即可重命名。工作原理P2P WebRTC CRDT直连传输数据不过中心服务器协作者之间通过WebRTC直接相连设计数据直接从浏览器到浏览器桌面端同理从不经过中心服务器。信令传输层实现在 trystero.ts基于 Trystero 的 MQTT 中继appId 为COLLAB_APP_ID openpencil/2见 constants.ts完成对等发现随后建立 WebRTC 连接并配置了公开的 STUN/TURN 服务器Google、Cloudflare 的 STUN 以及 openrelay 的 TURN含 TCP 传输以穿透 NAT。一个值得注意的实现细节Trystero 约每 5.3 秒向房间的 broker 广播一次存在因此经过两轮广播加上一次 WebRTC 握手房间内已有成员即可“认识”新加入者TRYSTERO_DISCOVERY_MS 12_000正是对这一发现周期的容错窗口trystero.ts。文档状态CRDT 自动合并文档状态使用CRDT无冲突复制数据类型并发编辑会自动合并、无需解决冲突。实现上是 Yjs每个房间会话持有独立的Y.Doc图层放入nodes地图、图片放入images地图session.ts本地编辑由bindCollabGraphEvents监听node:updated、node:created、node:reparented、node:reordered、node:deleted等编辑器事件合并为一次本地编辑LocalEdit再在单个 Yjs 事务内写入yjs-sync.ts远端变更由registerYjsObservers观察nodes与images反解后应用到场景图yjs-sync.ts。测试 concurrent-edits.test.ts、random-edits.test.ts 对并发与随机编辑做了系统性验证。图层树合并树形 CRDT移动和重排图层同样可以合并。每个图层都会记住它曾被移入的每一个父级以及它在兄弟中的位置每个对等端都依据这份历史推导出相同的图层树——即 Evan Wallace 的树形 CRDTmutable tree hierarchy算法。效果不同人发起的移动、重排、新建图层全部生效若两人同时移动同一图层其中一个移动会在所有对等端上胜出当同一时刻产生的移动会把两个图层互相放入对方内部时后发生的移动会被撤销若某图层的新父级恰好在这期间被删除该图层会回到原位。版本一致性约束房间内所有人都需要安装以相同方式记录图层树的 OpenPencil 版本记录方式不同的版本之间互不可见对方的房间。共享的树格式标记通过 awareness 字段treeFormatTREE_FORMAT广播并经由 shared-tree 下的字段与迁移逻辑fields.ts、migration.ts维护。房间的本地持久化与重连房间在本地持久化——刷新页面后你会自动以相同状态重新加入刷新时路由/share/room-id会重建会话先读取 IndexedDB 中的本地副本再通过信令重新发现并连接其他对等端。等待期间会话以ROOM_STATUS_TICK_MS 500毫秒的间隔轮询信令连接状态超过ROOM_UNREACHABLE_MS 20_000毫秒仍无法触达即判定房间不可达constants.ts、session.ts。实用提示浏览器与桌面端均可用协作功能同时支持 Web 版与桌面版桌面版通过openpencil://join链接从浏览器无缝接管房间房间 ID 加密学随机只有拿到链接的人能加入无需密码即具备访问门槛过期光标自动清理有人断开连接时其陈旧光标会被自动清除。相关阅读官方协作文档packages/docs/programmable/collaboration.md协作源码src/app/collab含 trystero.ts、session.ts、yjs-sync.ts、shared-tree协作测试tests/app/collabconcurrent-edits.test.ts、random-edits.test.ts、layer-tree.test.ts其他可编程接口文档packages/docs/programmable赞分享前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载相关推荐OpenPencil 实时协作指南基于 Yjs CRDT 与 WebRTC 的无服务器 P2P 设计协作OpenPencil 实时协作指南基于 Yjs CRDT 与 WebRTC 的无服务器 P2P 设计协作 OpenPencil 内置了基于浏览器到浏览器P2前端桌面应用AI 应用MCP 服务OpenPencil 实时协作完全指南基于 WebRTC 与 Yjs 的无服务器 P2P 协同编辑OpenPencil 实时协作完全指南基于 WebRTC 与 Yjs 的无服务器 P2P 协同编辑 导读 OpenPencil 项目仓库 https://l前端桌面应用AI 应用MCP 服务OpenPencil 实时协作编辑指南基于 WebRTC P2P、Yjs CRDT 与 IndexedDB 的房间协作机制全解析OpenPencil 实时协作编辑指南基于 WebRTC P2P、Yjs CRDT 与 IndexedDB 的房间协作机制全解析 本篇指南以 collabor前端桌面应用AI 应用MCP 服务上一篇scikit-learn 聚类模块完全指南sklearn.cluster 算法选型、原理与评估实践下一篇使用 Jest 测试 jQuery DOM 操作从事件监听、异步回调到 jsdom 测试环境创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考