Files
dsh_ai1net_server/交付物/用户组网群聊可行性评估-20260925.md
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

8.2 KiB
Raw Permalink Blame History

交付物 · 用户组网群聊可行性评估(环形网络 · 2026-09-25)

工作区:E:/ProgramData/AIProject/aliyun-dsh-server|基线:D:/github/dsh_shenxian 问:能否让用户组成环形网络做群组聊天、只有数据保存到服务器?群聊的技术特性(对话顺序、历史记录等)是否满足? 方法:① 只读取证现有覆盖网络能力 ② 联网核对业界群聊技术特性 ③ 逐条对照


§0 判定(先说结论)

  1. 「环形拓扑」不推荐 —— 三个硬伤(延迟随人数线性增长、单点断环、两两打洞成本 O(N²)),业界群聊无此形态。
  2. ✅ 但「用户之间点对点组网」本身可行,且底座已经在平台里 —— 打洞、分网隔离、直连优先回落、组密钥都已落地(src/net/relay/direct/ + content/)。
  3. 🔴 顺序与历史这两条,恰恰要求服务器必须是权威 —— 所以正确形态不是"P2P 取代服务器",而是 服务器定序落库(权威)+ 用户间直连(加速投递)。你说的"只有数据保存到服务器"与这个形态完全一致。
  4. 🔴 但有一个前置硬阻塞:云安全组未放行 ⇒ 真机打洞成功率实测 = 0 ⇒ 现在做 P2P 投递会全部回落中继,等于没做。

§1 先分清两个概念(你的设想里混在一起)

说法 含义 判定
环形拓扑(A→B→C→…→A) 严格指消息沿环逐跳转发 ❌ 不推荐(§2)
点对点组网(成员之间直连) 彼此能直连,拓扑不限 ✅ 可行,底座已在(§3)

⇒ 我按"你要的是用户之间能直连"来评估;若你确实要严格的环,§2 给出为什么不建议。

§2 为什么不推荐"环"

硬伤 具体
延迟随人数线性涨 N 人环上,一条消息到最远的人要 N/2 跳;10 人尚可,100 人就是 50 跳的排队
单点断环 环上任意一人掉线/断网 ⇒ 环断成两半(要补救就得双向环 + 重路由 ⇒ 又回到全互联)
两两打洞成本 O(N²) 每人要与其他所有人建直连 ⇒ 打洞次数按人数平方增长。🔴 这正是你们已记录过的 O(N²) 扇出问题
没有定序者 环只是拓扑,不提供顺序(见 §4-①)

业界群聊的拓扑只有两种:星型(服务器/中继为中心)、小群全互联(≤ 几十人)。没有用"环"的。

§3 已具备的能力(好消息 · 实测口径)

能力 落点 状态
打洞 / 直连 src/net/relay/direct/{candidate,punch}.ts ✅ 已落地(离线 NAT 模拟器 24/24 成功,p50 建连 155 ms)
直连优先、回落中继 content/runtime.ts 的 PEER_CHANNEL_ORDER = ['direct','wss'] ✅ 双通道已落地生产
块 id 复算闸门 取回的块必须复算 id 才对 ✅ 防"假绿"
分网隔离(用户可组独立网) dialers: Map<networkId, Set<hostId>>,没列到的一个都拨不动(默认拒绝) ✅ 零代码:新增一个 networkId 即可(ops / u:<userId> / 自命名)
一键加入 + 分组准入 overlay-node-join.cjs / overlay-node-admit.cjs ✅ 已落地
组密钥加密 按 (network, group) 的 AES-256-GCM,组内密文一致 ✅ 已落地
中继带宽节省(实测) 1 − 组数/节点数 ⇒ 4 人组 75%、16 人组 93.75% ✅ 内容面实测
🔴 云安全组放行 UDP 47 / 106 入站 21100/21115 仅放对端 /32 ❌ 未实施(唯一在册红) ⇒ 真机打洞 发 21 收 0

⚠️ 一处关键事实:上述 P2P 能力目前只用在「内容面」(插件的静态内容分发,按块)。 「消息面」零 P2P —— src/im/hub.ts 的扇出只有"本进程逐连接"与"交给外部连接层"两条路。 ⇒ 要在群聊里用 P2P,需要把消息面接上这套直连(新增接线,不是零成本)。

§4 群聊技术特性逐条对照(联网核对 · 5 个来源一致)

① 对话顺序 —— 🔴 这条决定了"服务器必须权威"

业界一致结论(OpenIM / WhatsApp 设计 / 系统设计手册,五篇同口径):

会话内必须强顺序一致(同一会话所有参与者看到的顺序严格一致); 做法 = 服务器在落库那一刻分配单调递增 seq,客户端按 seq 渲染、⛔ 不按本地到达时间。 全局顺序不需要(没人在乎两个不同群的先后)。 纯客户端时间戳做不到——时钟漂移 + 同毫秒并发无定序。

🔴 推论:seq 必须由落库那一步产生 ⇒ 定序点只能在服务器。这否掉了"纯 P2P 群聊"。 ✅ 你们已经这么做了:messages.seq = DB 分配的房内单调整数(权威序), lamport 只在同一 seq 冲突里做 tie-break、⛔ 不参与最终排序 —— 与业界口径逐字一致。

② 历史记录 —— 你说的"数据存服务器"正好满足

  • 历史 = 按会话分区、按 seq 聚簇的追加式日志(append-mostly)。
  • 离线补拉 = 客户端带上自己的游标,取"seq 大于游标"的那一段。
  • ✅ 现有:resume(游标补拉是断线重连的唯一补齐路径)。
  • 🔴 如果消息只走 P2P 而不落库 ⇒ 历史直接缺失 ⇒ 每条消息都必须落库,P2P 只做加速。

③~⑨ 其余特性对照表

# 特性 环网能否满足 现有平台 说明
③ 多设备同步 ❌ ⚠️ 部分 每设备需各自游标(last_read_seq / last_delivered_seq);现只有单游标补拉
④ 成员变更边界 ⚠️ 要重构环 ✅ 成员表 新成员能否看历史、踢出后是否即时停收 —— 现有成员表可判
⑤ 在线态 presence ❌ 环上要全互联 ✅ 已有心跳 + 1 s 批合并 + 收敛(防惊群)
⑥ 群 E2EE ⚠️ 密钥分发复杂 ✅ 方向已定 🔴 必须用群共享密钥(Megolm 化),⛔ 不能对 N 人各加密一次(O(N²))—— 已在册
⑦ 扇出成本 ❌ O(N²) 连接 ✅ 中继 = 一次发布;P2P 反而放大连接数
⑧ 单点故障 ❌ 断环 ✅ 两台中继冗余 + 抖动切流(实测切换 18.8–20.9 s)
⑨ CAP 取舍 — ✅ 已选 业界做法 = 最终一致 + 会话内强序;现有实现同向

§5 若要做,正确形态(架构选型 · 我已定,可推翻)

不做环。采用「服务器定序 + 直连加速」:

发消息 → 服务器落库(分配 seq = 权威序)──► 历史 / 补拉 / 多设备 都以此为源
           └─► 同时经覆盖网络直连推给在线的其他成员(能直连就直连,不能就回落中继)
  • 复用已有的 direct/(打洞)+ content/runtime.ts 的双通道模式(直连优先、回落 wss)+ 块 id 复算闸门那套防假绿思路。
  • 新增工作量:消息面接直连(现在只有内容面接了)+ 直连失败回落 + 防重放/去重。
  • 收益(按已有实测外推):中继带宽节省 1 − 组数/节点数;消息面需另测(⛔ 不是照搬内容面读数)。

🔴 顺序约束(必须先做的前置)

云安全组不放行 ⇒ 真机打洞成功率 = 0 ⇒ 先做消息面 P2P 会全部回落中继 = 白做。 ⇒ 顺序是:① 开云安全组 → ② 复测真机打洞率 → ③ 再决定要不要做消息面直连。 ⚠️ 云安全组只能你在控制台操作(我无云凭据,不得索取)。

§6 一个更容易被忽略的前提

即便 P2P 建成,"用户之间"要先在同一个覆盖网络里 —— 现有分网隔离是默认拒绝: 不在白名单的节点一个都拨不动。所以"让用户组成网络"这件事本身 = 先给这些用户建一个网 + 逐个准入(P1 已能一键加入)。

§7 边界

⛔ 本件零代码改动、未部署、未 commit/push、未动 47/106、未改任何别的工作区。 ⛔ 未登记下一棒(路线选择 + 云安全组操作均需你定)。