前端与蓝牙物联网(Bluetooth IoT)通信,本质上是在和设备的 GATT(Generic Attribute Profile)服务 进行数据交互。对于有 React/RN 背景的开发者来说,重点不仅是“怎么连”,更重要的是理解通信协议、数据格式和兼容性问题。
一、前端与蓝牙设备通信架构
典型架构:
React Native App
↓
Bluetooth API
↓
BLE协议
↓
设备(Service)
↓
Characteristic
↓
MCU(单片机)
↓
传感器
例如智能温湿度计:
手机
↓
连接设备
↓
读取温度特征值
↓
解析二进制数据
↓
展示UI
二、BLE核心概念
Service(服务)
类似接口分组。
例如:
Device
├── Battery Service
├── Temperature Service
└── Device Info Service
每个服务都有 UUID:
180F Battery
180A Device Information
Characteristic(特征)
类似接口字段。
例如:
Temperature Service
├── 当前温度
├── 当前湿度
└── 电量
UUID示例:
2A6E Temperature
2A6F Humidity
通信方式
读取
readCharacteristic()
设备 → 手机
写入
writeCharacteristic()
手机 → 设备
例如:
开灯
关灯
修改参数
Notify(通知)
最常用。
设备主动推送
例如:
心率变化
温度变化
GPS变化
三、React Native通信流程
以 react-native-ble-plx 为例:
1. 扫描设备
manager.startDeviceScan(
null,
null,
(error, device) => {
console.log(device.name);
}
);
2. 连接设备
const device =
await manager.connectToDevice(id);
3. 获取服务
await device.discoverAllServicesAndCharacteristics();
4. 获取特征
const services = await device.services();
5. 读取数据
const value =
await device.readCharacteristicForService(
serviceUUID,
characteristicUUID
);
6. 写入数据
很多设备协议要求:
JSON
Hex
Base64
例如:
await device.writeCharacteristicWithResponseForService(
serviceUUID,
characteristicUUID,
base64Value
);
四、实际项目中的协议设计
前端通常不会直接传 JSON。
常见是:
HEX协议
例如:
AA550101FF
含义:
AA55
协议头
01
命令
01
开灯
FF
结束位
前端发送:
开灯
↓
HEX编码
↓
Base64编码
↓
BLE发送
设备返回:
AA55020101FF
解析:
执行成功
五、兼容性问题(最重要)
Android碎片化
最常见问题。
不同厂商:
- 小米
- 华为
- OPPO
- vivo
- 三星
蓝牙实现存在差异。
常见问题
扫描不到设备
可能原因:
定位权限没开
蓝牙权限没开
系统限制后台扫描
Android 12+:
BLUETOOTH_SCAN
BLUETOOTH_CONNECT
必须动态申请。
自动断开
部分国产ROM:
锁屏
↓
系统省电
↓
断开蓝牙
解决:
前台Service
忽略电池优化
iOS兼容性
后台蓝牙
默认:
切后台
↓
连接断开
需要:
bluetooth-central
后台模式。
权限描述
NSBluetoothAlwaysUsageDescription
必须配置。
六、BLE版本兼容
设备可能支持:
BLE4.0
BLE4.2
BLE5.0
BLE5.2
手机可能支持:
BLE4.2
而设备:
BLE5.2
虽然能连接:
高级功能失效
例如:
- Long Range
- Extended Advertising
七、数据包长度问题
BLE单包很小。
默认:
20 Byte
很多新人会踩坑。
例如发送:
{
"deviceId": "123456",
"username": "admin"
}
可能超过限制。
需要:
分包
↓
发送
↓
重组
八、前端如何设计蓝牙SDK
企业项目通常不会直接在页面写蓝牙逻辑。
建议封装:
src
├── bluetooth
│ ├── manager.ts
│ ├── protocol.ts
│ ├── parser.ts
│ └── index.ts
例如:
Bluetooth.connect(id)
Bluetooth.send(cmd)
Bluetooth.subscribe(...)
页面:
await Bluetooth.connect(deviceId);
await Bluetooth.turnOnLight();
九、面试常考问题
如果面 RN、IoT、智能硬件公司,经常会问:
BLE和经典蓝牙区别
BLE:
低功耗
传输量小
IoT常用
经典蓝牙:
音频传输
耳机
音箱
Notify和Read区别
Read:
主动读取
Notify:
设备主动推送
为什么BLE要Base64
很多 RN 蓝牙库底层要求传输二进制数据,而 JavaScript 不直接处理原始字节流,因此会使用 Base64 作为中间编码格式。
如何解决大数据传输
MTU协商
分包
重传
CRC校验
对于你目前的前端经验(React + Vue + RN方向),如果未来想进入:
- 智能硬件
- 新能源汽车
- 智能家居
- 车联网
- 工业物联网
建议重点学习:
- BLE协议基础(GATT、Service、Characteristic)
- React Native 蓝牙开发
- Web Bluetooth API(浏览器蓝牙)
- MQTT协议
- TCP/WebSocket通信
- 设备协议设计(Hex、TLV、Protobuf)
- OTA固件升级流程
这些知识组合起来,已经属于“前端 + IoT”交叉领域比较有竞争力的技能栈。