
Chatto 多服务器架构解析Loom 架构、设备端目录与跨服务器身份如何工作【免费下载链接】chattoA fully-featured team and group chat application that you can easily selfhost.项目地址: https://gitcode.com/gh_mirrors/chatt/chattoChatto 是一个可自托管的完整团队群聊应用它的多服务器架构让你像使用 Discord 一样在一个客户端里同时连接多台 Chatto 服务器。本文带你理解支撑这一能力的三大核心设计Loom 日志架构、设备端服务器目录Server Catalogue、以及基于 OAuth 的跨服务器身份体系。一、Loom 架构单一事件日志驱动的服务器内核Chatto 的服务器端采用一种被称为Loom 架构全称 Log-Oriented Outcomes and Materializations面向日志的结果与物化的设计定义见 ADR-073。1. 一条权威事件日志EVT StreamLoom 架构的核心思想是所有持久化的领域决策都收敛到一条带乐观并发控制OCC的事件日志而不是散落在多个可变的数据库表里。在 Chatto 中这条主日志是名为EVT的 NATS JetStream 流。命令先读取已追平的投影状态再以 OCC 方式追加到日志追加成功返回一个持久化位置可作为读己之写的屏障用一句话概括数据流向commands → 决策 → 追加到 EVT 主日志 ├─ 顺序回放 → 物化内存/NATS/本地索引等读模型 └─ 持久投递 → 工作者 → 外部结果邮件、Webhook 等2. 物化Materializations是可丢弃的读模型房间摘要、未读数、在线状态等读模型都是从日志顺序回放出来的派生产物可以随时重建。它们的快照和检查点只是回放加速器绝不能反过来成为权威数据源。这正是备份、恢复和多副本扩展变得简单的关键——只需备份事件日志本身。3. 与多服务器架构的关系每台 Chatto 服务器都是一个独立的应用拥有独立的 NATS 账号与EVT流。客户端连接多台服务器时本质上是在与多个完全隔离的 Loom 域交互——互不共享状态、互不泄漏数据。这就是多服务器客户端能干净地逐服务器管理会话的底层原因。相关源码位于 cli/internal/core/ 与共享事件框架 pkg/events/。二、设备端目录你的服务器列表只存在本机1. 为什么服务器列表不跨设备同步早期版本曾尝试通过 Authling 账户数据服务同步已知服务器列表但这引入了第二个 OAuth 客户端、额外的运行时TinyBase和复杂的同步边界。最终 ADR-074 做了一个更克制的决定前端的服务器目录与所有逐服务器会话都是设备本地device-local的。理由是服务器列表属于应用偏好数据而不是身份状态。它不需要出现在你的每一台设备上。2. 目录与会话的边界分离ADR-064 确立了清晰的四块状态边界其中对多服务器体验最关键的是前两块状态所有者管什么服务器目录已知服务器 ID、不可变的地址origin、名称、图标、注册时间服务器会话设备本地的 Bearer 令牌、缓存的用户信息、重新认证状态Authling 会话全局身份提供方若配置了的话的授权与连接状态账户协调器跨边界操作如退出当前服务器、退出全部服务器关键语义已知服务器不等于已登录会话。一台服务器可以处于知道它但已登出的状态点击它即可重新发起正常的 Chatto OAuth 登录流程。3. 对你意味着什么换一台新电脑或新浏览器目录是空的除自动探测到的源服务器需要重新添加服务器在某台设备登出服务器不会影响其他设备上的会话前端不持有任何全局身份提供方的令牌攻击面更小客户端的这套注册表、会话与存储逻辑如今统一收敛在共享包chatto/client中见 ADR-111源码 packages/chatto-client/前端只保留 URL 路由和界面状态。三、跨服务器身份开放 OAuth CIMD 可轮换会话这是整个多服务器架构中最精巧的部分如何在不让运营者为每个前端在每台服务器做注册的前提下安全地登录任意远程服务器1. URL 是当前服务器的唯一事实来源多服务器前端通过 URL 段确定当前激活的服务器ADR-025-段 源服务器提供当前页面的那台主机名段 远程服务器例如chat.example.com没有当前服务器全局单例切换服务器就是切换路由作用域各服务器的连接与数据缓存完全隔离。2. CIMD客户端用元数据文档自证身份ADR-071 引入了CIMDClient ID Metadata Document任何兼容的公共客户端都可以用一个 HTTPS 元数据 URL 作为它的 OAuthclient_id文档中声明了精确的重定向 URI 与展示信息Chatto 授权服务器会主动拉取并校验这份文档从而在无需预注册的情况下获得稳定的客户端身份用户仍需显式同意首次授权Chatto 按用户 稳定客户端 ID记住同意管理员可以把已记录的客户端标记为可信或直接屏蔽屏蔽会撤销该客户端的所有可轮换会话这让客户端生态是开放的类似*的自由度同时保留了精确回调绑定、审计与撤销能力。Chatto 桌面端则使用固定内置标识chatto://desktop无需发布元数据文档。3. 可轮换 Bearer 会话15 分钟令牌 90 天续期窗口登录远程服务器后客户端获得的是 OAuth 授权码 PKCE 换来的可轮换会话ADR-079短生命周期访问令牌默认 15 分钟用于 ConnectRPC / HTTP / WebSocket 实时流量轮换刷新凭证客户端在到期前自动刷新后台无缝完成不打断你的聊天路由与实时投影续期窗口90 天内活跃即自动续期完全不活动则整窗过期防重放刷新使用一次性请求 ID检测到旧代次凭证被重放会直接撤销整个会话对普通用户的体验是连接多台服务器时每台都会自动保持登录状态你几乎感觉不到令牌在轮换。4. 会话与认证的安全细节源服务器使用HttpOnly Cookie同源远程服务器才使用设备本地的 Bearer 会话每台服务器独立登出、独立失效——一台服务器令牌失效只标记该服务器需要重新认证不影响其他服务器前端启用严格 CSPXSS 防护本身就是认证边界的一部分因为远程凭证存放在浏览器本地认证与会话行为的完整规范见 FDR-023四、总结三大设计如何协作层设计一句话概括服务器内核Loom 架构每台服务器一条权威事件日志物化读模型可随时重建客户端目录设备本地目录服务器列表是你的本机偏好不跨设备、不同步跨服务器身份开放 OAuth CIMD 可轮换会话无需预注册即可安全登录任意服务器令牌自动后台续期三者配合的结果是一台服务器是独立可信域一份目录是本地偏好一套开放而克制的 OAuth 协议负责把身份安全地借给任意服务器——这正是 Chatto 能像成熟商业产品一样舒适地支持多服务器的原因。延伸阅读架构决策记录docs/adr/Loom 架构定义ADR-073设备端目录决策ADR-074CIMD 开放客户端ADR-071可轮换会话协议ADR-079共享客户端源码packages/chatto-client/架构总览docs/ARCHITECTURE.md【免费下载链接】chattoA fully-featured team and group chat application that you can easily selfhost.项目地址: https://gitcode.com/gh_mirrors/chatt/chatto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考