11 个不稳定版本 (5 个重大更改)

0.7.0-alpha.2 2024 年 8 月 16 日
0.7.0-alpha.12024 年 7 月 30 日
0.6.0 2024 年 7 月 30 日
0.4.0 2023 年 12 月 14 日
0.1.4 2023 年 10 月 9 日

#2 in #server-connection

Download history 3/week @ 2024-04-26 5/week @ 2024-05-17 2/week @ 2024-05-24 4/week @ 2024-05-31 5/week @ 2024-06-07 3/week @ 2024-06-14 60/week @ 2024-07-05 7/week @ 2024-07-12 4/week @ 2024-07-19 226/week @ 2024-07-26 35/week @ 2024-08-02 3/week @ 2024-08-09

268 每月下载次数
用于 7 crates

MIT/Apache

78KB
776 代码行

aeronet

crates.io docs.rs

A light-as-air client/server transport library with first-class support for Bevy, providing a consistent API which can be implemented by different transport mechanisms.

试试示例!

启动服务器

cargo run --bin move_box_server

运行原生桌面客户端

cargo run --bin move_box_client

在浏览器中运行客户端

cargo install wasm-server-runner
cargo run --bin move_box_client --target wasm32-unknown-unknown

并连接到 http://[::1]:25565

查看 示例 文件夹中的源代码。

Screenshot of the move_box example, showing some server log output in the console, and two connected clients represented as boxes controlled by the user

传输

此 crate 的主要目的是提供一种 API,用于在客户端和服务器之间通过任何类型的连接传输消息 - 内部通道、网络、WASM 等。这是通过 ClientTransportServerTransport 特性来实现的。

当前可用的传输实现包括

  • aeronet_channel - 使用内存中的 MPSC 通道
    • 适用于非网络场景,如本地单人服务器
    • 目标: 原生 + WASM
    • cargo运行 --aeronet_channel --示例回声 --功能 "bevy"
  • aeronet_webtransport - 使用基于 QUIC 的 WebTransport 协议
    • 通用传输实现的良好选择
    • 目标: 原生(客户端 + 服务器)+ WASM(客户端)
    • cargo运行 --aeronet_webtransport --示例回声客户端 --功能 "bevy 危险配置"
    • cargo运行 --aeronet_webtransport --示例回声客户端 --功能 "bevy 危险配置" --目标wasm32-unknown-unknown
      • 需要安装 wasm-server-runner
    • cargo运行 --aeronet_webtransport --示例回声服务器 --功能 "bevy"
  • aeronet_steam - 使用Steam的NetworkingSockets API
    • 仍在开发中
    • 目标:原生
    • cargo运行 --aeronet_steam --示例回声客户端 --功能 "bevy"
    • cargo运行 --aeronet_steam --示例回声服务器 --功能 "bevy"

目标

本库的目标是尽可能通用

  • 支持尽可能多的传输协议
    • 你应该能够将几乎所有东西插入作为底层传输层,并且能够正常工作
    • 为此,aeronet提供了对某些协议元素的自己的实现,例如分段和可靠消息 - 请参阅aeronet_proto
  • 与Bevy集成
    • 为应用程序和游戏而构建,选用的抽象紧密适合Bevy的应用模型,以及其他类似框架
  • API简单
    • 底层传输的复杂性被抽象掉了,这既允许在实现上的灵活性,也减少了API用户的认知负担
    • 配置选项仍然公开,但总有一组合理的默认值
  • 对非异步代码友好
    • 此库抽象了与传输相关的异步代码,并公开了一个更简单的同步API。
  • 轻量级,占用空间小
    • 通过使用Bytes,该库最小化了数据的复制量,从而减少了分配
    • 通过占用小的内存空间实现可靠性、排序等功能

此库不旨在是

  • 一个高级应用程序网络库,具有复制、回滚等功能
    • 此库只关注数据负载的传输,而不是负载实际包含的内容
  • 异步库
  • #![无标准库]
  • 非客户端到服务器网络库(例如点对点)
    • 客户端预计最多只有一个连接到服务器 - 尽管这个服务器也可以是一个运行相同应用程序的客户端

概述

消息

API公开的最小传输单元是消息。消息表示为一个Bytes - 用于存储字节序列的容器,它允许零拷贝网络代码。用户需要赋予这些字节意义。

通道

通道定义了消息传递到另一端的方式,例如不可靠、可靠有序等。这些在某些协议中类似于“流”或“通道”,但通道是关于交付方式的抽象,而不是单个流或通道。支持的通道类型和因此提供的保证列在LaneKind中。

请注意,如果传输不支持通道,那么它本质上保证了通道提供的最强保证 - 即通信始终是可靠有序的。

通常,传输实现将要求您在创建时传递一个配置,该配置定义了传输可用的通道及其属性(例如,它是否可靠、有序等)。

Bevy插件

功能标志:bevy

此库提供了一些有用的项和类型,用于处理传输,可以将它们作为资源添加到您的应用程序中。但是,请注意,没有提供插件 - 而是您需要手动驱动传输事件循环。

条件

功能标志:condition - 依赖于getrandom,可能在WASM中无法工作

为了确保您的网络代码能够抵抗故障,常用的策略是添加人工的包丢失和延迟。此库通过condition模块提供了此功能。

协议

箱: aeronet_proto

这个箱提供了一组可重用的传输层抽象,可以被传输实现使用,如果它们已经不支持某些功能。这使得提供新的传输实现变得容易,因为你只需将这些功能插入到底层的字节流或其他传输使用的机制中。

bevy_replicon 集成

箱: aeronet_replicon

使用这个箱,你可以将任何 aeronet 传输插入到 bevy_replicon 作为后端,同时提供高级网络功能,如实体复制,同时仍然可以自由使用底层的任何传输实现。

入门指南

使用现有的传输

如果你想使用已支持的传输之一(你可能想这么做),将这个箱和传输实现箱作为依赖项添加到你的项目中

[dependencies]
aeronet = "version"
aeronet_whatever_transport_impl = "version"

该箱的版本与 aeronet 的所有官方子箱保持同步 - 使用你为传输使用的与 aeronet 相同的版本,这样就可以开始使用了。

要为你的传输创建一个值,以及如何配置它,请参阅传输的 README 中的 入门指南 部分。如果使用 Bevy,你应该将传输作为资源插入到你的应用程序中。否则,在主更新循环中可以访问的地方保存你的传输 - 你需要通过 poll 手动驱动它。

你可以使用特 ClientTransportServerTransport 来控制你的客户端或服务器,例如发送和接收消息。

客户端和服务器状态

该箱将客户端的连接抽象为未连接、正在连接或已连接;将服务器抽象为关闭、打开或已打开。默认情况下,客户端从未连接开始,服务器从关闭开始 - 你必须手动启动连接或打开服务器,提供诸如要连接的地址、要打开的端口等配置。这将根据传输实现而变化。

有关更多信息,请参阅 ClientStateServerState

管理连接

连接建立后

  • 使用 send 将消息缓冲起来,以便从这个对等方发送到另一侧
  • 使用 flush 刷新所有缓冲的消息,并通过传输实际发送它们
  • 使用 poll 更新传输的内部状态并接收有关发生情况的事件

建议你在应用程序的更新过程中使用 send 缓冲发送消息,然后在每个更新的末尾使用 pollflush 来完成更新。

将你的数据编码和解码到 Bytes 是你的责任。

use aeronet::bytes::Bytes;
use aeronet::client::{ClientEvent, ClientTransport};
use aeronet::lane::LaneIndex;

#[derive(Debug, Clone, Copy)]
enum AppLane {
    HighPriority,
    LowPriority,
}

impl From<AppLane> for LaneIndex {
    fn from(value: AppLane) -> Self {
        match value {
            AppLane::HighPriority => LaneIndex::from_raw(0),
            AppLane::LowPriority => LaneIndex::from_raw(1),
        }
    }
}

# fn run(mut client: impl ClientTransport, delta_time: web_time::Duration) {
let message: Bytes = Bytes::from_static(b"hello world");
client.send(message, AppLane::HighPriority).unwrap();

client.flush().unwrap();

for event in client.poll(delta_time) {
    match event {
        ClientEvent::Recv { msg, lane } => {
            let msg = String::from_utf8(Vec::from(msg)).unwrap();
            println!("Received on {lane:?}: {msg}");
        }
        _ => unimplemented!()
    }
}
# }

Bevy 支持

bevy aeronet
0.14 0.7
0.13 0.6

依赖关系

~0.5–42MB
~666K SLoC