3、网络拓扑与角色:Friend节点、Low Power节点、Proxy节点、Relay节点
蓝牙Mesh组网里,节点不是千篇一律的。每个节点可以扮演不同的角色,就像团队里有人负责转发消息,有人负责省电,有人负责给Wi-Fi设备搭桥。这一章,我把四种核心角色——Friend、Low Power、Proxy、Relay——掰开揉碎讲清楚,再聊聊它们怎么协作。
3.1 四种角色,各司其职
先看一张总览图,把角色和它们的关系理清楚。
3.2 Relay 节点——消息的搬运工
Relay节点是Mesh网络的脊梁。它的核心工作就一件事:收到消息后,判断要不要转发给邻居。
每个Relay节点内部维护一张消息缓存表,记录最近收到的消息序列号。如果收到重复消息,直接丢弃。这能防止消息在网络里无限循环——说白了就是防广播风暴。
Relay节点的工作流程:
- 收到一条Mesh消息
- 检查消息缓存:如果已经处理过,丢弃
- 检查TTL(生存时间):如果TTL ≤ 1,不再转发
- 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 | 全功能节点,承担核心角色 |
说白了,角色分配没有银弹。你得根据实际场景、设备硬件、功耗要求来权衡。我习惯先画一张网络拓扑图,标出每个设备的位置和供电方式,再决定角色分配。这样不容易出错。