#networking #channel #reliability #reliable #transport #unreliable #udp

turbulence

为游戏网络提供序列化、复用、可选可靠性和可选压缩的工具

5 个版本 (3 个破坏性更新)

0.4.0 2022年3月14日
0.3.0 2020年10月31日
0.2.0 2020年10月24日
0.1.1 2020年4月15日
0.1.0 2020年4月12日

游戏开发 中排名第 846

每月下载量 47
2 crates 中使用

MIT/Apache

140KB
2.5K SLoC

turbulence

我们会到达那里,但会有一段颠簸的旅程。


Build Status Latest Version API Documentation

适用于游戏的复用、可选可靠、异步、传输无关、反应器无关的网络库。

这个库实际上并不执行任何网络操作或以任何方式与平台网络API交互,它是一种将您提供的某种不可靠无序的传输层转换为一系列独立的网络通道的方法,每个通道都可以选择性地使可靠有序

现在理解这个库有什么用处的最好方法可能是查看 MessageChannels 测试。这是提供的最高级别、最简单的 API:它允许您定义 N 种可序列化的消息类型,定义每个单独通道的网络设置,然后为您提供一系列用于将数据包推入和从 MessageChannels 接口中提取数据包的句柄。用户预期将从输出端提取数据包并通过 UDP(或类似协议)发送,同时也从 UDP(或类似协议)读取输入数据包并传递它们。使用此库的唯一可靠性要求是,如果从远程接收数据包,则数据包必须完整且未损坏,除此之外,底层传输不需要提供任何可靠性或顺序保证。没有执行损坏检查的原因是许多传输层已经免费提供此功能,所以对于 turbulence 来说通常没有进行这种检查的必要。由于没有可靠性要求,简单地丢弃不通过一致性检查的输入数据包是合适的。

这个库以提供大量灵活性的方式构建,但并没有做什么来帮助您在游戏服务器和客户端之间建立网络连接。设置 UDP 游戏服务器是一个复杂的任务,而这个库旨在帮助解决这个难题的一个部分


这个库实际上做什么

turbulence 目前包含两个主要协议,并在它们之上构建了一些便利性

  1. 它有一个不可靠的无序消息协议,接受小于数据包大小的消息,并将它们合并,以便每个数据包发送多个消息。这是两个协议中较简单的一个,适用于位置数据之类的每tick更新,因为重发旧数据没有用。

  2. 它有一个可靠的有序传输,具有类似于TCP的流量控制,但更简单,没有自动拥塞控制。而不是拥塞控制,用户指定目标数据包发送速率作为协议设置的一部分。

turbulence 在这些之上提供

  1. 可靠和不可靠的 bincode 序列化类型通道。

  2. 一个可靠通道,用于自动合并和压缩的 bincode 序列化类型。

最后,这个库还提供了一个API,用于在单个数据包流中多路复用这些通道的多个实例,并提供了一些构建通道和按消息类型访问它们的方便方式。这就是 MessageChannels 接口提供的内容。

你可能提出的问题

你为什么需要这样的东西呢?

只有当以下大多数或所有情况都成立时,你才需要这个库

  1. 你有一个实时网络游戏,TCP或类似TCP的协议不适用,并且由于延迟原因必须使用像UDP这样的不可靠协议。

  2. 你有一个需要发送快速不可靠数据(如位置)以及可靠游戏相关数据(如地形数据、聊天或复杂实体数据)的游戏,这些数据带宽密集。

  3. 你有几个独立的数据流,并且它们需要不相互阻塞或阻塞快速不可靠数据。

  4. 使用许多不同的OS级网络套接字是不切实际的或不受欢迎的(或不可能的),或者使用深入到OS的现有网络库,或者只是假设存在UDP套接字。

为什么你需要这个库,XYZ协议不是已经做了这件事吗 (其中XYZ是纯TCP、纯UDP、SCTP、QUIC等)

从某种意义上说,这个库相当于同时拥有多个UDP连接和带宽受限的TCP连接。如果你已经能够这样做,而且这对你来说是可以接受的,那么你可能会考虑只做这件事而不是使用这个库!

这个库在某种程度上也类似于QUIC之类的产品,因为它为你提供了多个独立的数据通道,它们不会相互阻塞。如果QUIC最终支持真正不可靠、无序的消息(据我所知,目前这只是一个提议的扩展?)并且它有一个你可以使用的实现,那么使用QUIC当然是一个可行的选项。

所以这个库包含了一个类似TCP的实现,尝试实现这样复杂的东西不是通常的坏主意吗?

可能吧,但由于它为较低的静态带宽限制而设计,并且不涉及拥塞控制,这减少了大量的复杂性。尽管如此,这是这个库中最复杂的部分,但它经过了良好的测试,并且在到目前为止我所运行的环境中确实至少是可行的。它并不复杂,可以被认为是“你可以合理地编写和使用的最简单的类似TCP的东西”。

您不应像使用TCP一样使用这个库中的可靠流。一个可能不适合通过这个库处理的好例子是流资产数据,您应该为需要尽可能快速传输且始终由带宽限制而不是游戏性能限制的数据使用单独的通道。

这里的可靠流用于通常受游戏性能限制但可能出现峰值的情况,您希望限制带宽,以防止这些峰值减慢重要数据或其他玩家的速度。

为什么这个库如此通用?它太通用,所有东西都基于像 PacketPoolRuntime 这样的特性,这使得它难以使用。为什么不能直接使用 tokio / async-std?

PacketPool 特性不仅允许自定义数据包类型,还用于类似多路复用器的东西,因此它具有双重作用。 Runtime 存在的原因是我在一个网页浏览器中使用这个库连接到远程服务器时使用了 webrtc-unreliable,我必须手动在Web API之上实现它,目前这并不简单。

当前状态/未来计划

我在一个真实项目中使用过这个库,并在真实互联网上工作,它确实有效。我还使用链路调节器在游戏中对其进行测试,以模拟各种级别的数据包丢失和重复,据我所知,它按预期工作。

该库目前可用,但API绝对不能被视为稳定,它可能还会经历很多变化。

在不久的将来,可能需要其他类型的通道,它们提供介于可靠性和有序性保证之间的保证。

最终,我希望可靠通道具有某种拥塞避免机制,但这可能需要在某些方面进行协作。

该库迫切需要更好的示例,特别是使用例如 tokio 和 UDP 的完整示例,但设置这样的示例本身就是一项庞大的任务。

许可证

turbulence 许可证受以下任何一个许可证的约束:

由您选择。

依赖关系

~1.5–2.3MB
~48K SLoC