把 ROUTER_LATE 讲明白:该用在哪,不该用在哪

原理

自从我们之前聊过 如何选择合适的角色 之后,Meshtastic 又新增了一个基础设施角色:ROUTER_LATE。这个角色名字看起来直白,但实际工作方式、适用场景和副作用,如果只看字面,很容易误判。

这篇文章最值得看的地方,不是它能不能让你自己的链路变好,而是它会如何影响整张 mesh。因为在 Meshtastic 这种单频共享、带宽极其有限的网络里,一个角色选错,影响的往往不只是你自己。

以下内容翻译自 Meshtastic 官方博客文章《Demystifying ROUTER_LATE》。原文发布于 2025 年 9 月 25 日。英文原文链接:https://meshtastic.org/blog/demystifying-router-late/

ROUTER_LATE 的定位到底是什么?

ROUTER_LATE 的设计目标,是给大型或复杂网络里的盲区做基础设施补位。典型场景是:某一簇节点被山体、峡谷、建筑群等障碍遮挡,看不到现有 ROUTER 站点。

它是一个强制重播角色:只要收到的数据包还没到 hop 上限,它都会重播。

但它并不是为了替代高质量骨干 ROUTER。更准确地说,ROUTER_LATE 适合放在对流量通行很关键、但覆盖面并不优秀的位置。也就是那种不够理想、但又必须补位的站点。

官方特别强调:不要把它当作家里屋顶扩展器来用。因为 ROUTER_LATE 会重播它能听到的几乎所有包,这会显著增加区域内空口占用。类似用法如果变多,mesh 会很快出现拥堵、碰撞和丢包,甚至直接不可用。这在慢速调制(例如 LONG_FAST)下更明显。

如果你的诉求只是做一个屋顶基站,应该优先考虑 CLIENT_BASE

重播时序:ROUTER_LATE 是怎么礼让的

Meshtastic 的带宽限制非常严苛,因此它不会使用 OSPF、BGP 这类依赖大量控制面通信的复杂路由协议。它采用的是角色分工 + 随机延迟 + 基于信号质量的时序偏置,让数据包更可能走有效路径,同时尽量减少无谓重播。

只要一个包的剩余 hop 大于 0,它就有资格被重播;如果 hop 已经是 0,节点处理完后会直接丢弃,不再转发。

三个争用窗口(Contention Windows)

Meshtastic 的重播发生在三个互不重叠的时间窗口中,可以理解为节点收到包之后的三段时隙:

窗口 时长 角色 说明
Early 很短 ROUTERREPEATERCLIENT_BASE* 第一时隙。会抢占其他角色,并可能让非基础设施角色取消自己的重播。
Default 正常 除 Early 角色外的大多数角色 默认重播时隙。
Late 正常 ROUTER_LATE 最后时隙。如果 ROUTER_LATE 在前面听到别人先重播,它会改到这里再发。

除了 ROUTER_LATE 之外,其他角色只会在各自所属窗口内尝试重播。

ROUTER_LATE 是特例:正常情况下,它行为几乎和 CLIENT 一样,会在 default 窗口按 CLIENT 的计时逻辑重播;但如果它在此前任意窗口里听到别的节点已经先重播了同一个包,它不会取消,而是把自己的重播延后到 late 窗口。

这就是它作为礼让型重播器的本质。它优先让现有网络按原本路径运行,自己作为补位。除了空口占用更高这一点外,在该位置部署 ROUTER_LATE 的路由影响,基本等价于部署一个 CLIENT

* CLIENT_BASE 只有在包的来源或目标是收藏节点(favorite)时,才会在 early 窗口重播;其他情况下仍按普通 CLIENT 在默认窗口工作。

随机时序与 SNR 偏置

在每个争用窗口内,节点会先加一个随机延迟再发包。随后,这个延迟会按接收该包时的信噪比(SNR)再调整:

  • SNR 越差(通常链路更差、距离更远),延迟越短;
  • SNR 越好(通常链路更近、质量更高),延迟越长。

这么做的目的,是让多个节点听到同一包时,不至于同时发射;同时让更远的节点更容易优先拿到重播机会。SNR 当然不是距离的完美代理,但和距离存在一定相关性。平均来看,这会让每一跳走得更远。

何时取消重播,何时改到 Late

为了保护单频共享信道不被塞满,除 ROUTERREPEATERROUTER_LATE(以及 favorite 场景下的 CLIENT_BASE)之外,其他角色一旦听到别人已经重播同一包,就会取消自己的重播并丢弃该包。

ROUTER_LATE 不会取消,而是把重播延后到 late 窗口。

ROUTER_LATE 也会丢包吗?

会。虽然它默认几乎都转发,但有两个明确例外:

  1. 包到达时 hop 已是 0。此类包被视为到此为止,不会继续传递。
  2. 发送队列(TX queue)已满时,如果新到的可重播包优先级更高,队列里最低优先级的包会被丢弃。这个问题在繁忙网络或慢速调制下更常见。ROUTER_LATE 特别容易触发该情况,因为它会把延后到 late 窗口的包先压在 TX 队列里等待发送。

常见问题(FAQ)

为什么不能把 ROUTER_LATE 直接放屋顶长期跑?

因为它会重播几乎所有听到的包,显著增加共享频率上的流量负担,进而导致拥堵、碰撞和丢包。总流量过高时,mesh 性能会明显下降,严重时直接不可用。

如果你仍坚持把它当屋顶角色,至少要持续盯住两个指标:ChUtil(共享空口占用)和 AirUtilTX(本节点发射空口占用)。如果 ChUtil 超过 25%,或者 AirUtilTX 高于约 7% 到 8%,应停止这种配置,避免拖垮全网。

另外,ROUTERREPEATER 也同样不适合普通屋顶场景,甚至更不适合,因为它们会抢占其他角色。

为什么我的包有时会走普通 CLIENT,而不是本地 ROUTER_LATE?

因为 ROUTER_LATE 是礼让型重播。如果某个 CLIENT 当时位置更占优,或者只是随机计时中先发了,包就可能先走它。ROUTER_LATE 仍会重播,但你可能在结果上看不出来,因为包已经先经别的路径抵达了。

为什么包会先走 ROUTER / REPEATER,而不是我这里的 ROUTER_LATE?

ROUTERREPEATER 会在重播上抢占其他角色。只要它们在覆盖范围内,包通常先经它们转发。若这类节点部署位置不理想,还可能导致 hop 过早耗尽。

为什么 traceroute 里看不到 ROUTER_LATE?

通常就是前面两条原因:要么被别的节点先发了,要么被 ROUTER / REPEATER 抢占了路径。

为什么经过 ROUTER_LATE 的流量有时偏慢?

因为它如果听到别的节点先重播,会把自己的转发延后到 late 窗口。这个额外等待在慢速调制(例如 LONG_FAST)下会非常明显。

为什么理论上该走 ROUTER_LATE 的流量会丢?

你所在区域的共享频率大概率已经很忙,ROUTER_LATE 的 TX 队列被塞满后,会优先丢低优先级包。

另外,mesh 上某些操作会在极短时间内产生大量数据包,队列可能在几秒内从空变满。

我现在在次优位置跑 ROUTER / REPEATER,要不要改成 ROUTER_LATE?

如果这个节点必须重播才能让其覆盖范围内节点顺利接入整网,那就改 ROUTER_LATE。如果它是屋顶节点,优先 CLIENT_BASECLIENT

我是周围唯一 ROUTER,但海拔也没到离谱高度,要不要换 ROUTER_LATE?

如果你的覆盖真的非常优秀,请继续用 ROUTERROUTER 的含义就是:它声明自己是范围内流量的最佳路径。

也请注意,ROUTER / REPEATER 会让其覆盖范围内多数重播角色取消自己的重播(例外是 ROUTERREPEATERROUTER_LATE 和 favorite 场景下的 CLIENT_BASE)。因此,只有在位置确实适合抢占式转发时才该部署 ROUTER

我在某地只能听到别人,但别人听不到我。要不要加一个 ROUTER_LATE?

不建议。更合适的是在附近加一个 CLIENT。这样它会重播那些没走出去的包,但不会把本来就能互听到的流量重复放大,避免额外占用空口。

这在内置天线受限的设备上很常见,例如 T1000-E

车上能不能放 ROUTER_LATE?

大多数情况下不建议。少数例外是:你临时把车辆作为中继平台,为徒步队伍等提供看不到主网时的临时覆盖。

即便如此,活动结束后也要及时改回更合适的角色。

如果你只是想让车载节点照顾你进楼后的手持通信,一般应选 CLIENT(你能收但发不出去)或 CLIENT_BASE(双向都需要帮助)。

在车上长期固定一个 ROUTER_LATE,能帮到整张网吗?

通常不能,而且往往弊大于利。ROUTER_LATE 不是移动角色,长期车载使用多数情况下会制造的问题多于解决的问题。

小结

ROUTER_LATE 的核心价值,不是更猛的中继,而是克制地补位。它通过默认像 CLIENT、必要时延后到 late 窗口再发的策略,尽量不破坏原有路由秩序,同时在关键盲区提供额外可达性。

如果你把它放在真正需要基础设施补位的点位,它会非常有价值;如果把它当万能增程器到处开,mesh 很快就会用拥堵给出反例。

本文作者: Hays Chan | 陈希

本文链接: https://meshcn.net/demystifying-router-late/