25 个不稳定版本
0.13.0 | 2023 年 6 月 20 日 |
---|---|
0.12.1 | 2022 年 11 月 25 日 |
0.12.0 | 2022 年 10 月 14 日 |
0.11.0 | 2022 年 1 月 27 日 |
0.4.0 | 2019 年 3 月 29 日 |
#3 in #negotiation
367,276 每月下载量
在 379 个crate中使用 (直接使用4个)
83KB
1.5K SLoC
多流选择协议协商
此crate实现了 multistream-select
协议,这是libp2p用于在连接或子流上与远程端协商使用哪个应用层协议的协议。
注意:此crate主要用于libp2p的核心组件,通常不单独使用。
角色
在I/O流上使用多流选择协商协议的两个节点,根据其作为 拨号器(或 发起者)或作为 监听器(或 响应者)的角色来区分。因此,拨号器扮演主动角色,驱动协议,而监听器则对收到的消息做出反应。
拨号器有两个选项:它可以从监听器支持的所有协议列表中选择一个协议,或者直接建议一个协议。无论如何,所选协议都会发送给监听器,监听器可以接受(通过回显相同协议)或拒绝(通过返回表示“不可用”的消息)。如果建议的协议不可用,拨号器可以建议另一个协议。这个过程会继续,直到达成协议,产生一个 Negotiated
流,或者拨号器用尽了所有替代方案。
参见 dialer_select_proto
和 listener_select_proto
。
协商
Negotiated
代表一个已经确定使用某种协议的 I/O 流。默认情况下,使用 Version::V1
时,在发送协商协议的应用数据之前,协商至少需要进行一个专用的往返消息交换。存在一个变体 Version::V1Lazy
,如果拨号器只支持一个协议,则允许 0-RTT 协商。在这种情况下,当拨号器确定要使用的协议时,DialerSelectFuture
在协商数据被刷新之前会返回一个 Negotiated
I/O 流。此时,它期望从流中读取的第一个消息是对该协议的确认。这种行为允许拨号器立即发送与协商协议相关的数据,以及剩余的协商消息。但是请注意,如果一个拨号器对堆叠在彼此之上的不同协议连续执行多个 0-RTT 协商,可能会触发不支持中间协议的监听器的不希望的行为。有关详细信息,请参阅 dialer_select_proto
和 Version::V1Lazy
的文档。
示例
对于拨号器
use async_std::net::TcpStream;
use multistream_select::{dialer_select_proto, Version};
use futures::prelude::*;
async_std::task::block_on(async move {
let socket = TcpStream::connect("127.0.0.1:10333").await.unwrap();
let protos = vec!["/echo/1.0.0", "/echo/2.5.0"];
let (protocol, _io) = dialer_select_proto(socket, protos, Version::V1).await.unwrap();
println!("Negotiated protocol: {:?}", protocol);
// You can now use `_io` to communicate with the remote.
});
依赖项
~1.2–2MB
~39K SLoC