在 rust-libp2p 0.55.0 中,SubstreamRequested(子流请求)是多路复用连接下,远程 Peer 向本地发起协议通信的核心触发事件,其概念需结合 libp2p 的「多路复用」基础设计理解:
1. 前置基础:连接与子流的关系
libp2p 中,两个 Peer 建立的底层连接(如 TCP+Yamux、QUIC)支持「多路复用」—— 即一个物理连接可以同时承载多个独立的「子流(Substream)」,每个子流是双向字节流,对应一个特定的 StreamProtocol(如自定义 RPC 协议 /my-rpc/1.0.0、Kademlia 协议 /ipfs/kad/1.0.0)。
这种设计的核心价值是:避免为每个协议单独建立连接,减少网络开销,提升连接复用率。
2.SubstreamRequested的定义
当远程 Peer 希望与本地 Peer 用某个特定协议通信时,会向本地发起一个「子流创建请求」,此时 rust-libp2p 会触发 SubstreamRequested 事件,告知本地:
“有一个针对 [X] 协议的子流请求从 Peer [Y] 发来,请处理这个新子流”
3. 触发场景(0.55.0 中)
SubstreamRequested 仅在入站通信中触发(本地主动发起的子流属于 “出站请求”,不会产生此事件),典型场景包括:
- 远程 Peer 向本地发起 RequestResponse RPC 请求;
- 远程 Peer 向本地发起 Kademlia DHT 查询;
- 远程 Peer 尝试与本地建立 Gossipsub 订阅流。
4. 0.55.0 中的处理流程
SubstreamRequested 会被分发到对应协议的 Behaviour(由于每个 Behaviour 会注册自己支持的 StreamProtocol),以 RequestResponseBehaviour 为例:
- 本地 RequestResponseBehaviour 已注册协议 /my-rpc/1.0.0;
- 远程 Peer 发起针对 /my-rpc/1.0.0 的子流请求,Swarm 触发 SubstreamRequested;
- Swarm 将该事件分发给 RequestResponseBehaviour;
- RequestResponseBehaviour 接受子流,通过 Codec 序列化 / 反序列化字节流,将其转换为 Request 事件(后续由业务逻辑处理);
- 处理完成后,再通过该子流返回 Response,最终关闭子流。
5. 0.55.0 中的关键特性
在 0.55.0 版本中,SubstreamRequested 的处理被整合到 Behaviour 的事件循环中:
- 若使用 #[derive(Behaviour)] 生成的组合式 Behaviour,Swarm 会自动将子流请求分发给对应协议的 Behaviour(无需手动路由);
- 支持配置「最大并发子流数」(如 RequestResponse 的 max_concurrent_streams),避免单 Peer 占用过多子流资源。
总结
SubstreamRequested 是 libp2p 多路复用模型的核心事件之一,它让不同协议可以在同一个底层连接上独立通信,是实现 “单连接多协议” 的关键机制;在 0.55.0 中,其处理逻辑被进一步封装到 Behaviour 中,简化了协议层的开发复杂度。
