团队聊天这件事,本质上没什么技术难度:账号、群组、私信、文件、历史消息。难的是「谁来维护」。自建 Rocket.Chat 要一台服务器、一套数据库、一个备份策略;买 SaaS 又要接受数据放在别人那里。
EdgeChat 选了第三条路:把整套系统放进 Cloudflare 的免费生态里,用 Workers、D1、KV、R2、Durable Objects 拼出来。没有服务器要维护,没有数据库进程要盯着,没有证书要续期。

它提供什么
定位是团队内部 IM:管理员创建账号,不开放自助注册,但支持注册邀请。有公开群组、私有群组、一对一私信,历史消息分页、文件消息、头像管理,还有定时硬删除过期消息。
管理后台是一级导航结构:仪表盘、用户管理、注册邀请、网站设置。有个细节挺聪明——可以直接在浏览器里调 GitHub Compare API 比对源码仓库,检查当前部署是不是最新版本,不需要在服务器上跑任何定时任务。

加密设计要说清楚
这是我觉得最需要讲明白的一点,因为很容易被误解。
新写入的消息和附件用 AES-256-GCM 做服务端加密,历史数据不回填。这不是端到端加密。 密钥在 Worker 上,Worker 在完成会话权限校验之后解密内容再返回给客户端。也就是说,如果你能拿到 Worker 的环境变量和 D1 的数据,理论上可以解开消息。
但它在另一个方向上做了取舍:管理后台不提供消息正文查看入口,配套移除了消息搜索和完整会话查看页面及 API。管理员能管账号、能看统计,但不能翻聊天记录。这个设计对「公司内部需要一个能说点实话的地方」是有意义的。
要真正的端到端加密,得把密钥放在客户端,服务端只做密文中转。那会牺牲搜索、多端同步和后台管理,是另一个产品了。
Telegram 桥接
通过 Bot 做双向消息桥接,EdgeChat 的群组和 Telegram 的群可以实时互通。这个功能对小团队挺实用:外部协作者不一定愿意再装一个 IM,但他们大多有 Telegram。
代价是桥接过来的消息绕过了端到端边界,得接受 Telegram 那边的可见性。用之前想清楚哪些群开、哪些群不开。

技术栈
前端 Vue 3 + Vue Router + Vite,后端 Cloudflare Workers + Hono,实时消息走 Durable Objects 的 WebSocket,数据和文件用 D1、KV、R2。
这套组合的关键在 Durable Objects。聊天最难的是「同一条消息要同时推给在线的所有人,还要保证顺序」,传统做法是靠一台有状态服务器或者 Redis 广播。Durable Objects 给了每个会话一个单实例对象,天然串行、天然有状态,WebSocket 长连接直接挂在上面。
用 D1 存结构化数据、R2 存文件、KV 存配置和缓存,是 Cloudflare 生态里比较标准的分配方式。全部在免费额度内可以跑起一个小团队。
部署
本地开发:
npm install # 安装依赖
npm run dev:frontend # 前端开发
npm run dev:demo # 纯前端 demo(独立端口和构建目录)
npm run build # 本地构建
npm run deploy # 本地手动发布生产部署推荐用仓库自带的 .github/workflows/deploy-worker.yml,推送到 master/main 或者手动触发 workflow_dispatch 就自动部署。也支持 Docker,仓库里有 DOCKER.md 和 docker-compose.yml。
在线 Demo 是纯前端演示站,API 和 WebSocket 都在浏览器内存里模拟,刷新就重置。看界面可以,别拿它评估性能。

适合谁,不适合谁
适合:十到几十人的小团队,想要一个自己可控、又不想养运维的站内 IM;已经在用 Cloudflare、对厂商锁定不敏感的项目;需要 Telegram 桥接做外部协作的场景。
不适合:需要真正端到端加密的合规场景;消息量很大、要求强一致和复杂检索的场景;不能接受数据存在 Cloudflare 的组织。
还有一个现实问题:Cloudflare 的免费额度对小团队够用,但 D1 的行数、R2 的存储和出口、Durable Objects 的请求数都有上限。人数一多,账单会从 0 变成几十美元,这仍然比养一台服务器便宜,但要有预期。
文章评论