跳到主要内容
ZeroRelay 说自己零服务器,但评论区最刺耳的一条是:这怎么敢叫直接浏览器到浏览器?

ZeroRelay 说自己零服务器,但评论区最刺耳的一条是:这怎么敢叫直接浏览器到浏览器?

盖文
盖文

· 阅读约 12 分钟

ZeroRelay 这个项目我一开始没当回事,一个开源 P2P 文件分享工具,满大街都是。直到评论区 Sam 那句“这怎么敢叫直接浏览器到浏览器”被顶起来,我才又回去把仓库里的 ARCHITECTURE.md 翻了一遍。翻完发现它把圈内反复出现的那个原型问题摆得很直白:隐私由架构保证,和隐私由政策保证,到底差在哪。结论先放一句:ZeroRelay 的服务器端确实做到了接近“零内容存储”,但它的隐私承诺目前只到“服务器不碰内容”这一层,还没到“对端是否真的收到、会话断了之后内容去了哪”这一层。信源主要是作者 Kushal Baral 发在 dev.to 的介绍、仓库里的 ARCHITECTURE.md,还有评论区几个真实上手用过或参与过的人。这篇不预测,只把这个项目实际怎么搭、哪里还没搭上记下来。

说“无服务器”的时候,多半不是没有服务器,是服务器被压成一层很薄、又常常不主动提的信令层。ZeroRelay 也没跑掉。它没有中央存储、没有数据库、不要求注册,这都没错;但信令还在,由 Cloudflare Durable Object 按房间处理,只交换加入/离开消息和 ICE candidate。说得再直白一点:服务器不碰消息、文件、头像这些内容,它只碰“谁来了、谁走了、怎么找到对方”这层连接元数据。很多项目把这层省略不提,ZeroRelay 至少没省略,作者还专门把它写进架构文档,理由是透明性:要审计服务器实际存了什么、没存什么,可以自己看。

这个项目把“开源让你来审计我”当第一理由,说实话我见过的真不多。大多数 P2P 项目开源是为了部署方便,或者干脆就是不想自己维护中央服务。ZeroRelay 的逻辑反过来:代码摆出来是给你查它有没有撒谎。这个逻辑很硬——一旦服务器代码可审,“我只是不查你”和“我查不了你”的区别就出来了。作者自己的说法是,数据不走信令服务器,每个 peer 自己就是数据库,内容通过 Dexie 塞进浏览器 IndexedDB,然后 WebRTC data channel 直接广播给已经连上的 peer。架构上写得很清楚:每个 peer 收到的都是对端直接发来的,Cloudflare DO 只管信令,没有中央存储。这部分我是信的。

问题出在评论区,而且不是围观的人,是上手用过的人。

Alex Shev 那条评论被顶得挺高,他说这模式最强的地方是“隐私由架构而不是政策保证”,但真正难的是失败体验——重连、会话过期、交付状态提示。这句话一半是夸,一半是指出真正的问题。作者回得也坦白,说“无需信任服务器正是核心”,承认干净处理网络掉线和重连是 P2P 应用的最终挑战。

“最终挑战”四个字放得不轻,可我去 ARCHITECTURE.md 里能看到的传输路径里翻,没有找到“重连之后发件如何恢复”这个答案。浏览器 IndexedDB 是每个 peer 自己持有的持久化层,确实能把内容存下来,但“按条目选择保留期限”这里多了一个很锋利的粒度:只能选本次会话、5 分钟、1 小时、1 天或永久。这个设置放在中央存储架构里是合理的产品功能,放到 P2P 里问题就变了:一旦允许“仅本次会话”,对端关掉页面之后,内容消失发生在哪一端?发送方还是接收方?这个答案会直接决定你在一家公司里拿它分享代码库临时片段时,能不能回看上一轮会话里别人发来的补丁。ZeroRelay 的架构文档里有没有这段,我没有第二个信源确认;但作者在评论里没有继续展开这个点,至少已经说明这不是他当前愿意放进文档的问题,更像一个产品层面还没处理的边角。

Alex Shev 又追了一句,P2P 隐私要成为可用的产品,恢复过程必须足够平常,用户需要清楚看到重连、过期、部分交付和对端是否收到文件等状态。这一句直接把“架构性隐私”从哲学里拉回了产品里。你不再需要信任服务器,这很好;但你开始需要信任自己的浏览器没有把对端发送状态吃掉了。一个聊天软件里“已送达”“已读”是产品标配,但在 P2P 里这个状态机不是白拿的。ZeroRelay 现在没有把这套状态做成透明的,那用户就只能猜:对方到底收没收到?是不是有一条 file chunk 没到?还是对端根本没连上我?

接着就是 Sam 那句最刺耳的。他问,在需要 TURN 才能实用的情况下,项目怎么能自称“直接浏览器到浏览器”。作者的回答是:跨网络传输尚未支持,当前严格限定在局域网内共享,所以局域网内是 100% 直接浏览器到浏览器。这个回答在措辞上没问题,但他绕过了关键:目前只有 STUN,没有 TURN。如果传输只在同一局域网内可用,那“全球范围可用”这句话只意味着对等节点发现是全球可用的,不是数据传输全球可用。这个差别很重要。Cloudflare DO 做 WebSocket over TCP,确实可以让世界不同地方的浏览器通过信令找到彼此,但只要两边对称 NAT 不合作,WebRTC data channel 建立不起来,就什么内容也传不了。信令可达和媒体可达,在 P2P 里从来不是一回事。

我观察到一个模式:不少 WebRTC 原型项目先做 STUN,不做 TURN,然后把“未支持跨网络”埋在中部,把“全球发现”放在前部。不算撒谎,但会误导那种只扫前半段的人。ZeroRelay 的作者把它写成了“跨网络传输尚未支持,欢迎社区贡献 TURN 支持”,坦白程度在同类型项目里已经算高,但“全球范围可用”这个短语还是给太早了。我的判断很简单:一个需要 TURN 才能跨网工作的 P2P 应用,在没有 TURN 时,它的“直接浏览器到浏览器”只对同一 WiFi 下的两台机器有效。这个判断不新鲜,评论者 Cyrille37 已经用更老的方式点过一遍:snapdrop.net 运行多年,但只能用于本地网络。

问题还不是“它现在只能本地网络”,而是“它把架构性隐私作为卖点时,恰好只覆盖到了本地网络这一层”。本地网络里两个浏览器直接连上,发文件确实不经过任何服务器,这是真的;但谁会在本地网络里对一个文件传输工具产生隐私焦虑?本地网络里最常用的替代品是 AirDrop,它的确仅限苹果设备,不然就是 U 盘、SCP,或者干脆开个 HTTP 临时服务。ZeroRelay 确实比这几样都轻,打开网页、建个房间、传就是了。但它真正能替代的场景,是会议室里两台笔记本传一个安装包,而不是你从公司内网给外网的合作方发一份不能落服务器的文件。后一个场景才是架构性隐私真正值钱的地方,而它现在恰恰不支持跨网。

作者对开源原因的解释还有一句:让用户能自己部署信令 worker。这句我倒是喜欢。Cloudflare DO 是托管在 Cloudflare 上的,即使代码开源,跑在 CF 上的那套 worker 仍然不是用户自己的。作者的意思是,你可以自己搭一套信令服务器,让整个系统彻底不经过你能审计之外的任何基础设施。这把“信任服务器”推到最弱的一步:不是不需要服务器,而是每个人都可以自己成为那个服务器。这个意识很对,现实门槛不低:要会部署 Next.js 应用,要懂 Cloudflare Workers 和 DO,要维护一整套 room 生命周期。技术栈里列的是 Next.js 15、React 19、Zustand、Dexie v4、WebRTC、Cloudflare Workers 与 Durable Objects、Tailwind CSS v4、Biome、TypeScript、Husky。完整是完整,完整不等于轻量。一个声称“不用注册、不用数据库”的小工具,真自托管起来依然是全套现代前端工程。

这里有个小地方我注意到了,但应该没人关心:状态管理用 Zustand,结合“内存和 localStorage 持久化”。每个前端项目都这么干,可一旦从隐私角度读,就有点意思。真正持久化在 IndexedDB 里的是聊天内容、笔记、文件这类用户数据;localStorage 里的是什么,清单里没拆。我不猜它是房间密码还是 UI 状态,猜了也没法交叉核实。但作者如果愿意写清楚,审计性会更强。现在只能是“本地有个东西会持久化,但没说清是什么”的状态。这条我只有一个来源,先标未证实放着。

房间密码这里,项目介绍写的是“由 Cloudflare DO 执行的房间级密码”。这个写法很干净:密码校验放在服务器端,而不是发送端与接收端之间做端到端加密。它意味着服务器知道你进了哪个房间、有没有带对密码,但不知道你进去之后说了什么。这是典型的“信令有上下文、内容无上下文”的边界。要传一份高度敏感的东西,房间密码只能防陌生对端,不防信令服务器知道你在这个房间里出现过。几乎所有带房间概念的 P2P 应用都会碰到这个,ZeroRelay 没装不知道,但也没主动解释“房间里能看到谁”这件事对隐私的影响。可能作者觉得这是显学,不用写。

评论者 Jyoti Poudel 说参与了贡献,很高兴看到 ZeroRelay 上线,感谢 Kushal 领导项目。只有这一条,我不放大,但可以记个事实:这不是完全孤立的个人项目,至少有人通过贡献进了仓库。对一个想“透明到可自行部署”的项目,有第二个贡献者不是小事,但离“社区能接住 TURN 支持”还差得远。TURN 不是搭一个静态资源服务器,它涉及中继服务器、带宽成本、认证、限流,甚至一套能向 TURN server 发 signaling 指令的 worker 改动。作者说欢迎社区贡献 TURN 支持,我翻完目前能查到的公开信息,看不出有实际的设计草稿或接口预留。那这个欢迎听起来更像一句礼貌的话,不是一个任务。

如果只把 ZeroRelay 当成技术实验,它做对的事其实不少:全开源、无中央存储、信令与内容分离、按条目保留期限、可自托管。这几样放在一起,放在今天大部分“开源但服务器不透明”的项目旁边,已经能把作者想表达的那个“审计代替信任”的态度立住。可如果读者以为它已经是一个能解决“不想把文件交给云端”的日常工具,那就要失望:它现在是传输层可审计、交付层不可审计的作品。用户能审计服务器没存内容,但审计不到对端有没有把内容收完整;用户能自己部署信令服务,但还跨不过两个办公网之间的 NAT。这个割裂,恰恰是作者和 Alex Shev 对话里都点到但没人继续往下挖的那部分。

还有个小问题我写到这才意识到——ZeroRelay 被称为“应用”,但安装方式是从落地页打开在线演示,清单里没有任何桌面版或移动版。这意味着“浏览器即客户端”是它唯一形态。好处是上手轻,坏处是浏览器后台标签页被杀、网络切换、便携设备锁屏,都会成为比桌面应用更频繁的重连场景。Alex Shev 说的恢复过程必须“足够平常”,在移动浏览器上尤其难做。这也不是 ZeroRelay 特有的问题,但产品化 P2P 隐私这条路上,他们比谁都更需要解决,因为用户不会去理解“标签页休眠导致对端断开”这种解释,他们只会觉得“发过去的东西没了”。

几个值得盯的信号,盖文不下注,只列出来一起看:

一、ZeroRelay 仓库里后续是否出现 TURN 相关实现或接口设计,哪怕是一份 discussion,也能判断作者对“跨网”是认真还是停在欢迎二字。

二、ARCHITECTURE.md 下次更新时是否加入“会话过期/重连/部分交付”这段状态语义,或者作者是否在别处补上“对端是否收到”的状态描述——这一步比上 TURN 还重要。

三、作者对评论里 Sam 的质疑是否再有回应,尤其会不会把“全球范围可用”这个说法拆成“发现全球可用,传输当前局域网可用”。

四、有没有第二个或第三个贡献者开始参与,尤其是接手信令、DO、或 TURN 这类后端任务的人;只是 UI Contribution 不够说明问题。

五、项目之后是否在技术栈里悄悄加进数据库或中央状态,一旦出现,就说明纯 P2P 在某些使用场景下被现实妥协了,那也值得记一笔。

这五条都是可核验的公开信号,到时候回头看,比现在下结论说“这项目行/不行”靠谱。先记到这,有更准确信源、尤其是真在本地试过传输的朋友,欢迎匿名补充。

盖文
盖文

用信源 + 数据 + 内部 how-it-works 记录大厂怎么运作,分层标注、不下注。

查看主页 →