文章
一个进程里该有几个Endpoint?什么时候共享,什么时候隔离?
目录
- 一、先给出结论
- 二、为什么「一个 Endpoint」通常是正确答案?
- Endpoint 的本质再强调一次
- Endpoint 内部已经能做的事(很多人低估了)
- 三、什么时候「共享 Endpoint」是正确的?
- ✅ 场景 1:同一个应用 / 同一个身份
- ✅ 场景 2:库 + 上层应用
- 这是非常“工业级”的设计。
- 四、什么时候「必须拆成多个 Endpoint」?
- ❌ 错误理由(很多人会犯)
- ✅ 正确理由 1:身份不同
- ✅ 正确理由 2:安全 / 信任域隔离
- ✅ 正确理由 3:网络策略根本不同
- 五、一个非常重要但容易忽略的点
- Endpoint ≠ Session ≠ Connection
- 六、结合你现在的 sendme / iroh 场景
- 你的真实需求是:
- 所以你的设计应该是:
- 七、一句「工程级」总结
一、先给出结论#
绝大多数情况下:一个进程只需要一个 Endpoint。 只有当“身份 / 网络语义不同”时,才应该拆分多个 Endpoint。 记住这句话,后面所有内容都是在解释它。
二、为什么「一个 Endpoint」通常是正确答案?#
Endpoint 的本质再强调一次#
Endpoint = 节点在网络中的“身份 + 可达性 + 连接管理器” 它不是:
- 一个 socket
- 一个连接
- 一个请求上下文 而是:
“我这个进程,在整个网络中的存在方式”
Endpoint 内部已经能做的事(很多人低估了)#
一个 Endpoint 内部就已经支持:
- 多个并发连接
- 同时 serve + connect
- 多路复用(QUIC stream)
- 自动 NAT 路径切换
- 多 peer 并存 👉 你几乎不可能因为“不够用”而需要第二个 Endpoint
三、什么时候「共享 Endpoint」是正确的?#
✅ 场景 1:同一个应用 / 同一个身份#
Tauri App
├── 文件发送
├── 文件接收
├── 状态同步
└── 控制指令
✔ 一个 Endpoint 原因:
- 同一 NodeId
- 同一网络策略
- 共享 NAT 映射 / Relay
- 连接可复用(省资源、提速)
✅ 场景 2:库 + 上层应用#
比如你现在做的:
sendme (library)
↑
tauri app
✔ Endpoint 由上层创建,传入库中使用
pub struct SendService {
endpoint: Endpoint,
}
这是非常“工业级”的设计。#
四、什么时候「必须拆成多个 Endpoint」?#
这是重点。
❌ 错误理由(很多人会犯)#
- “功能不同”
- “模块不同”
- “代码想解耦” 这些都不是理由。
✅ 正确理由 1:身份不同#
如果你需要:
- 同一进程
- 多个“逻辑节点”
- 在网络中表现为不同的人
一个进程 = 模拟多个独立节点
那么: ✔ 每个身份 = 一个 Endpoint 典型场景:
- P2P 测试工具
- 节点模拟器
- 多账号系统
✅ 正确理由 2:安全 / 信任域隔离#
例如:
- 一个 Endpoint 用于公网
- 一个 Endpoint 用于内网
- 一个 Endpoint 只用于匿名通信 因为 Endpoint 内部共享:
- 私钥
- 中继关系
- 已建立的连接 👉 如果这些不能共享,就必须拆。
✅ 正确理由 3:网络策略根本不同#
比如:
- 一个 Endpoint 禁用 relay
- 一个 Endpoint 强制走 relay
- 一个只监听内网 这已经是不同网络实体了。
五、一个非常重要但容易忽略的点#
Endpoint ≠ Session ≠ Connection#
很多人潜意识是:
一次 send → 一个 endpoint
这是 完全错误的直觉(但很常见)。 正确的层级是:
Endpoint
└── Connection (peer)
└── Stream (task / request)
你应该:
- 长期持有 Endpoint
- 短期创建 Connection
- 极短期使用 Stream
六、结合你现在的 sendme / iroh 场景#
你的真实需求是:#
- 一个 Tauri App
- 扮演一个 P2P 节点
- 多次发送 / 接收
- GUI 生命周期长
所以你的设计应该是:#
App 启动
└── 创建 Endpoint(一次)
├── send()
├── receive()
├── show_progress()
└── background tasks
❌ 不要:
- 每次 send 新建 Endpoint
- 每次 receive 新建 Endpoint 这会导致:
- NAT 映射反复重建
- Relay 重复注册
- ticket 行为变得“看似诡异”
七、一句「工程级」总结#
Endpoint 是“节点级”的对象,不是“操作级”的对象。 或者用更狠的话说: 你创建 Endpoint 的次数,应该和你在现实世界中“创建新身份”的次数一样少。