Skip to content

Reliability Modes

b23r0 edited this page Oct 12, 2026 · 4 revisions

English · 简体中文

五种可靠模式

可靠性、有序性和“新状态是否替代旧状态”是三个不同问题。先决定消息的业务语义,再选模式。

模式 重传 接收语义 适合的消息
Unreliable 不重传 尽力交付,可能丢失或乱序 可丢弃音效、短暂特效、独立采样
UnreliableSequenced 不重传 根据序列过滤已经过时的消息 高频位置快照、朝向、光标位置
Reliable 未确认时重传 可靠但不保证交付顺序 相互独立的事件、可按 ID 处理的任务
ReliableOrdered 未确认时重传 同一通道按发送顺序交付 命令序列、聊天、状态增量、大消息
ReliableSequenced 未确认时重传 可靠帧带序列过滤,旧状态可能被跳过 希望最终收到且可覆盖旧值的完整状态

可靠交付以连接保持有效为前提;连接断开时应处理错误。ReliableSequenced 的“可靠”不代表每个历史状态都交给应用。

Unreliable:丢一条也没关系

例如场景中的短暂火花,每一条都是独立表现,丢掉一个不会破坏下一帧。应用不要把库存扣减、付款或必须处理的操作放在这里。

UnreliableSequenced:别把旧位置补回来

发送完整的位置快照 A、B、C,C 已先收到时,迟到的旧快照无需让角色倒退。网络丢失 C 时,该模式不会为它补发;应用通常持续发送更新。

适合能独立解释的完整状态。如果 B 表示“在 A 上增加 1”,跳过 A/B 可能使状态错误。

Reliable:事件必须到,顺序不重要

例如几项彼此独立的资源通知或任务结果。乱序到达后用事件 ID 关联请求即可。如果第二条操作依赖第一条,改用 ReliableOrdered 或在业务层明确建立依赖。

传输确认不是事务提交。应用断线重试同一个业务请求时,仍然需要请求 ID 和业务去重。

ReliableOrdered:顺序就是语义

例如“创建对象 → 修改对象 → 删除对象”、聊天记录和差量同步。先到的后续消息可能需要等待缺失的前序消息补齐,这是同一通道的队头阻塞。

可以为相互独立的有序业务使用不同通道:

socket.send_with_order_channel(&chat, Reliability::ReliableOrdered, 0).await?;
socket.send_with_order_channel(&world_update, Reliability::ReliableOrdered, 1).await?;

这里只展示发送部分,chat 和 world_update 都必须以 0xfe 开头。跨通道没有顺序保证。通道仍共享连接窗口、CPU、socket 和网络带宽;它们不是互不影响的独立连接。与其他 RakNet 实现互通时请核对通道范围;示例使用 0 和 1。序列模式与有序模式会涉及同一通道的状态,独立业务尽量使用独立通道,混用前验证对端行为。

ReliableSequenced:重要的是更新后的状态

例如低频配置快照、某个对象的当前目标。未确认的帧会重传,但接收端可以跳过过时的状态。不要用于必须完整执行的命令或连续增量。若要“每条必须处理”,应选择 Reliable 或 ReliableOrdered。

大消息怎么处理

当前发送路径只有 ReliableOrdered 自动分片。其余四种模式超过单帧大小会返回 PacketSizeExceedMTU,不会自动升级为其他模式。

当前实现的单帧应用有效载荷上限按协商 MTU 减 60 B 计算;默认名义 MTU 为 1,400 B,因此此阈值为 1,340 B,包含应用数据的 0xfe。这是本项目当前发送实现的阈值,不是所有 RakNet 实现的通用上限。

大快照可以改用有序传输;如果坚持序列模式,需要自行设计分块 ID、完整性校验、重组限制和“完整快照可替换”的语义,不能直接把每个分块当作可丢弃的新状态。

相关:消息限制 · 小包合并 · 可靠模式源码

报文格式、索引语义、分片限制和重传算法详见 RakNet 协议参考。

Clone this wiki locally