3、网络拓扑与角色:Friend节点、Low Power节点、Proxy节点、Relay节点

蓝牙Mesh组网里,节点不是千篇一律的。每个节点可以扮演不同的角色,就像团队里有人负责转发消息,有人负责省电,有人负责给Wi-Fi设备搭桥。这一章,我把四种核心角色——Friend、Low Power、Proxy、Relay——掰开揉碎讲清楚,再聊聊它们怎么协作。

3.1 四种角色,各司其职

先看一张总览图,把角色和它们的关系理清楚。

蓝牙Mesh节点角色与协作关系图 蓝牙Mesh节点角色与协作关系 Relay 节点 转发消息,多跳核心 Proxy 节点 桥接GATT与Mesh Friend 节点 缓存消息,辅助省电 Low Power 节点 电池供电,间歇唤醒 未配设备 通过Proxy入网 说明: • 实线箭头表示消息转发/中继关系 • 虚线箭头表示Friend与Low Power之间的缓存/轮询关系 • 未配设备通过Proxy节点(GATT承载)加入Mesh网络

3.2 Relay 节点——消息的搬运工

Relay节点是Mesh网络的脊梁。它的核心工作就一件事:收到消息后,判断要不要转发给邻居。

每个Relay节点内部维护一张消息缓存表,记录最近收到的消息序列号。如果收到重复消息,直接丢弃。这能防止消息在网络里无限循环——说白了就是防广播风暴。

Relay节点的工作流程:

  1. 收到一条Mesh消息
  2. 检查消息缓存:如果已经处理过,丢弃
  3. 检查TTL(生存时间):如果TTL ≤ 1,不再转发
  4. TTL减1,重新打包,广播出去

我在项目里遇到过一个问题:某个智能灯控网络,消息延迟特别高。查了半天,发现所有节点都开了Relay功能,导致同一个消息被转发了七八次。后来我建议只让主干节点开Relay,叶子节点关掉,延迟立刻降下来了。

经验之谈:不是所有节点都需要做Relay。电池供电的设备尽量别开Relay,否则电量撑不过一周。我一般只在市电供电的节点上启用Relay,比如智能插座、网关。

3.3 Low Power 节点——省电是第一要务

Low Power节点(LPN)是为电池供电设备设计的。它大部分时间都在睡觉,只有需要收发消息时才醒来。

但问题来了:如果LPN在睡觉,别人发给它的消息怎么办?这就引出了Friend节点。

LPN会找一个Friend节点结对。Friend帮它缓存消息,等LPN醒来后再去取。LPN的唤醒间隔可以配置,从几百毫秒到几秒不等。

注意:LPN和Friend的结对关系不是永久的。如果LPN移动位置,或者Friend节点离线,LPN需要重新扫描并建立新的Friend关系。我在做智能门锁项目时,就遇到过LPN频繁切换Friend导致消息丢失的情况——后来把扫描间隔调短才解决。

3.4 Friend 节点——LPN的贴心管家

Friend节点的作用很明确:为LPN缓存消息,并在LPN轮询时把消息发给它。

Friend节点需要维护一个Friend表,记录每个结对LPN的信息,包括:

  • LPN的地址
  • 缓存的消息队列
  • Friend Offer参数(窗口大小、接收延迟等)

一个Friend节点可以同时服务多个LPN。但要注意,每个LPN只能有一个Friend。

参数 说明 典型值
ReceiveWindow LPN唤醒后监听窗口大小 100ms ~ 500ms
ReceiveDelay LPN发送轮询后到开始监听的延迟 10ms ~ 100ms
PollTimeout LPN两次轮询的最大间隔 1s ~ 60s

我个人习惯把PollTimeout设成3秒。太短了费电,太长了消息延迟高。你想想看,一个智能灯泡,按了开关要等5秒才亮,用户肯定骂娘。

3.5 Proxy 节点——Mesh世界的翻译官

Proxy节点解决了一个实际问题:手机、平板这些设备没有Mesh协议栈,它们只支持传统的蓝牙GATT。怎么让它们跟Mesh网络通信?

Proxy节点在中间做翻译。它同时运行两套协议:

  • GATT承载:跟手机通信,收发Proxy PDU
  • Mesh承载:跟Mesh网络通信,收发Mesh消息

手机通过GATT连接Proxy节点,发送Mesh消息。Proxy节点把消息转成Mesh格式,广播到网络里。反过来,Mesh网络里的消息也会通过Proxy节点推送给手机。

Proxy协议的核心:Proxy节点和手机之间传输的是Network PDU,不是Application Data。这意味着手机端需要自己实现Mesh协议栈的上层(网络层、传输层、应用层)。Proxy节点只负责网络层的转发。

我记得有一次做调试,手机连上Proxy节点后发不出消息。抓包一看,Proxy节点没有配置NetKey。嗯,这个坑我踩过,后来在配置工具里加了个检查,确保Proxy节点至少有一个NetKey才能工作。

3.6 角色之间的协作关系

四种角色不是孤立的,它们共同构成了Mesh网络的通信骨架。

Relay ↔ Proxy:Proxy节点本身也可以开启Relay功能。这样手机通过Proxy发出的消息,可以直接由Proxy转发给其他Relay节点,不需要额外跳转。

Friend ↔ Low Power:这是最典型的结对关系。LPN休眠时,Friend帮它收消息;LPN醒来后,Friend把缓存的消息一股脑发给它。

Proxy ↔ Friend:手机可以通过Proxy节点,间接控制LPN。手机发消息给Proxy,Proxy转发给Friend,Friend缓存,等LPN醒来再取。

一个节点可以同时扮演多个角色。比如一个市电供电的智能网关,可以同时是Relay、Proxy、Friend。但要注意,角色越多,资源消耗越大。我建议根据设备硬件能力合理分配角色。

避坑指南:我曾经在一个项目里,把所有节点都配成了Friend+Relay+Proxy。结果网络里Friend Offer满天飞,LPN扫描时收到几十个Offer,选择困难。后来我规定:只有网关级别的节点才启用Friend功能,普通节点只做Relay。

3.7 角色配置实战建议

最后,我整理了一份角色配置清单,供你参考:

设备类型 推荐角色 原因
智能灯泡(市电) Relay 市电供电,适合转发消息
智能门锁(电池) Low Power 省电优先,偶尔唤醒
智能插座(市电) Relay + Friend 位置固定,可服务附近LPN
手机App Proxy Client 通过GATT连接Proxy节点
网关(市电) Relay + Proxy + Friend 全功能节点,承担核心角色

说白了,角色分配没有银弹。你得根据实际场景、设备硬件、功耗要求来权衡。我习惯先画一张网络拓扑图,标出每个设备的位置和供电方式,再决定角色分配。这样不容易出错。