1. 蓝牙Mesh网络基础:Mesh网络拓扑、节点与中继、发布/订阅模型
各位同学,咱们正式开始这门课。第一讲,先把地基打牢。
蓝牙Mesh,说白了,它不是传统蓝牙那种「一对一」或者「一对多」的广播模式。它是一种多对多的网络。你想想看,一个智能灯泡要跟一百个开关通信,用经典蓝牙得累死。Mesh就是来解决这个问题的。
1.1 Mesh网络拓扑:不是星型,是网型
传统蓝牙是星型拓扑,一个中心节点连一堆外围设备。中心挂了,全完蛋。Mesh不一样,它是网型拓扑。
每个节点都可以跟周围的节点通信。消息像水一样,从源头扩散出去。没有单点故障,可靠性高很多。
我记得刚接触Mesh时,有个误区:以为所有节点都必须互相可见。其实不是。Mesh只要求相邻节点能通信就行。距离远的,靠中间节点接力传过去。
核心要点:Mesh网络没有中心节点。每个节点既是终端,也是潜在的转发者。这种结构天然支持大规模设备组网。
我画了一张图,帮你直观理解Mesh拓扑和传统星型拓扑的区别:
1.2 节点与中继:谁在干活?
Mesh网络里,节点不是平等的。它们有不同的角色。我个人习惯把节点分成四类:
| 节点类型 | 功能描述 | 典型场景 |
|---|---|---|
| 中继节点 | 接收并转发消息,扩展网络覆盖范围 | 吸顶灯、中继器 |
| 低功耗节点 | 不参与中继,定期休眠省电 | 传感器、门磁 |
| 朋友节点 | 为低功耗节点缓存消息 | 网关、常供电设备 |
| 代理节点 | 让非Mesh设备(如手机)通过GATT接入Mesh | 手机、平板 |
这里有个坑,我踩过。有一次项目里,我把所有节点都配成了中继节点。结果网络里消息满天飞,大量重复转发,功耗也上去了。
避坑指南:不是所有节点都需要当中继。中继节点越多,网络冗余越好,但消息洪泛也越严重。我建议:中继节点占比控制在30%-50%,其余节点设为低功耗或普通节点。
中继的工作原理其实很简单。当一个节点收到消息,它会检查:
- 这条消息我有没有转发过?(防止环路)
- 消息的TTL(生存时间)还有没有剩余?
- 这条消息是不是发给我的订阅组?
如果都满足,它就转发出去。TTL减1。TTL到0,消息就丢弃。
1.3 发布/订阅模型:消息怎么传?
这是Mesh最巧妙的设计之一。它不是点对点发消息,而是用发布/订阅模型。
每个节点可以订阅一个或多个组地址。节点也可以向某个组地址发布消息。所有订阅了这个组的节点,都会收到消息。
你想想看,这多方便。一个开关发布「开灯」消息到组地址0xC001。所有订阅了0xC001的灯泡,同时亮起。不需要知道灯泡的具体地址。
个人经验:我在做智能家居项目时,把客厅所有灯都订阅到同一个组地址。一个面板开关控制整个客厅。后来客户要分区控制,我只需要把灯分配到不同的组,开关也对应不同的组。改配置就行,不用动硬件。
发布/订阅模型的核心元素有三个:
- 发布者:发送消息的节点。比如开关、传感器。
- 订阅者:接收消息的节点。比如灯泡、执行器。
- 组地址:消息的「频道」。发布者和订阅者通过组地址关联。
组地址有三种类型:
| 地址类型 | 范围 | 用途 |
|---|---|---|
| 固定组地址 | 0x0000 - 0x00FF | 系统保留,如所有节点、所有中继节点 |
| 动态组地址 | 0xC000 - 0xFFFF | 用户自定义,如「客厅灯组」、「卧室灯组」 |
| 虚拟组地址 | 基于UUID | 临时或动态场景,如「日落模式」 |
嗯,这里要注意。发布/订阅模型跟传统蓝牙的GATT通知完全是两码事。GATT是中心-外设模型,Mesh是去中心化的。后面章节我会详细讲怎么用GATT服务把手机接入Mesh,那就是代理节点的活儿了。
最后,我用一张流程图总结一下消息在Mesh网络中的完整旅程:
好了,这一章的基础概念就这些。Mesh的拓扑、节点角色、发布/订阅模型,是后面所有内容的地基。你把这些搞清楚了,后面讲GATT代理、讲模型绑定,你才不会晕。