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

Download history 112026/week @ 2024-04-22 86611/week @ 2024-04-29 96154/week @ 2024-05-06 101268/week @ 2024-05-13 98350/week @ 2024-05-20 95527/week @ 2024-05-27 84985/week @ 2024-06-03 91822/week @ 2024-06-10 84380/week @ 2024-06-17 92165/week @ 2024-06-24 75716/week @ 2024-07-01 81930/week @ 2024-07-08 97581/week @ 2024-07-15 96134/week @ 2024-07-22 83811/week @ 2024-07-29 86611/week @ 2024-08-05

367,276 每月下载量
379 个crate中使用 (直接使用4个)

MIT 协议

83KB
1.5K SLoC

多流选择协议协商

此crate实现了 multistream-select 协议,这是libp2p用于在连接或子流上与远程端协商使用哪个应用层协议的协议。

注意:此crate主要用于libp2p的核心组件,通常不单独使用。

角色

在I/O流上使用多流选择协商协议的两个节点,根据其作为 拨号器(或 发起者)或作为 监听器(或 响应者)的角色来区分。因此,拨号器扮演主动角色,驱动协议,而监听器则对收到的消息做出反应。

拨号器有两个选项:它可以从监听器支持的所有协议列表中选择一个协议,或者直接建议一个协议。无论如何,所选协议都会发送给监听器,监听器可以接受(通过回显相同协议)或拒绝(通过返回表示“不可用”的消息)。如果建议的协议不可用,拨号器可以建议另一个协议。这个过程会继续,直到达成协议,产生一个 Negotiated 流,或者拨号器用尽了所有替代方案。

参见 dialer_select_protolistener_select_proto

协商

Negotiated 代表一个已经确定使用某种协议的 I/O 流。默认情况下,使用 Version::V1 时,在发送协商协议的应用数据之前,协商至少需要进行一个专用的往返消息交换。存在一个变体 Version::V1Lazy,如果拨号器只支持一个协议,则允许 0-RTT 协商。在这种情况下,当拨号器确定要使用的协议时,DialerSelectFuture 在协商数据被刷新之前会返回一个 Negotiated I/O 流。此时,它期望从流中读取的第一个消息是对该协议的确认。这种行为允许拨号器立即发送与协商协议相关的数据,以及剩余的协商消息。但是请注意,如果一个拨号器对堆叠在彼此之上的不同协议连续执行多个 0-RTT 协商,可能会触发不支持中间协议的监听器的不希望的行为。有关详细信息,请参阅 dialer_select_protoVersion::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