一、协议选型:物联网通信的第一道选择题
物联网 App 与设备之间的通信是整套系统的"神经系统"。协议选型不当,轻则连接不稳定,重则影响整个系统可用性。目前主流的轻量级通信协议有三个:MQTT、CoAP、LwM2M。
1.1 MQTT ------ 异步消息总线的王者
MQTT 基于发布/订阅模式,报文头部仅 2 字节,支持三个 QoS 级别。它的最大优势是解耦:设备只管发布数据,App 只管订阅感兴趣的主题,双方不需要知道对方的存在。
适用场景 :多设备协同、云端通信、需要可靠送达的控制指令。
版本提示 :推荐使用 MQTT 5.0,增加了会话过期、原因码等实用特性。
常见踩坑:
-
QoS 1/2 会带来重复消息,App 端需要做幂等处理。
-
断线重连后,订阅关系可能丢失,需在
connect成功回调中重新订阅。
1.2 CoAP ------ 窄带网络的轻量级选手
CoAP 基于 UDP,头部仅 4 字节,采用类 HTTP 的请求/响应模型。实测表明,在 NB-IoT 模组上 CoAP 单次通信能耗远低于 MQTT,非常适合电池供电的传感器。
适用场景 :超低功耗、窄带网络(如 NB-IoT)、资源受限设备。
注意:CoAP 默认使用 UDP,需要自己处理报文重传和顺序问题。
1.3 LwM2M ------ 设备全生命周期管理
LwM2M 基于 CoAP,定义了标准化的设备信息、固件升级等对象模型,适合需要远程运维的场景。
1.4 协议选型速查表
| 场景 | 推荐协议 | 理由 |
|---|---|---|
| 智能家居、车联网 | MQTT | 成熟生态,QoS 保障 |
| 户外传感器、水表气表 | CoAP | 极低功耗,UDP 无连接 |
| 工业设备远程运维 | LwM2M | 标准对象模型,固件升级完备 |
| 实时音视频控制 | WebSocket + WebRTC | 低延迟,双向流 |
⚠️ HTTP 仅适合作为云端服务之间的辅助接口,不宜直接用于设备与 App 的长连接通信。
二、跨平台开发:一套代码,两端运行
物联网 App 通常需要同时覆盖 Android 和 iOS。跨平台框架能大幅降低维护成本。
2.1 Flutter
-
特点:自绘 UI,性能接近原生,AOT 编译启动快。
-
推荐插件:
-
BLE:
flutter_blue_plus(持续维护版本) -
MQTT:
mqtt_client
-
-
踩坑 :iOS 上使用 BLE 必须在
Info.plist中配置NSBluetoothAlwaysUsageDescription,否则闪退。
2.2 React Native
-
特点:基于 JavaScript,生态丰富,热更新方便。
-
推荐插件:
-
BLE:
react-native-ble-plx -
MQTT:
react-native-mqtt(需结合原生模块)或websocket模拟
-
-
踩坑 :Android 12+ 必须同时申请
BLUETOOTH_SCAN和ACCESS_FINE_LOCATION权限,否则扫描不到设备。
2.3 Kotlin Multiplatform (KMP)
-
特点:共享业务逻辑(状态机、协议解析),UI 可各自原生或使用 Compose Multiplatform。
-
推荐库 :
kable(跨平台 BLE)、kotlinx.coroutines(异步)。 -
优势:完全避免双端逻辑不一致,且无性能损耗。
2.4 跨平台架构策略
核心原则:业务逻辑跨平台复用,硬件访问通过原生模块注入。
// 伪代码示例:跨平台层定义接口
abstract class BluetoothScanner {
Future<List<Device>> scan();
}
// Android/iOS 各自实现该接口,通过依赖注入提供给 UI 层
代码共享率:通常可达 80%~90%(不含 UI 样式微调)。
三、设备连接:从扫描到握手
3.1 近距离连接:蓝牙 BLE
Android 关键步骤:
-
申请权限(Android 12+ 需要
BLUETOOTH_SCAN和BLUETOOTH_CONNECT) -
获取
BluetoothAdapter,开启扫描 -
回调
onScanResult,过滤出目标设备 -
调用
connectGatt,在onConnectionStateChange中处理连接结果 -
发现服务
discoverServices,读写特征writeCharacteristic
iOS 关键步骤(Core Bluetooth):
-
CBCentralManager管理扫描和连接 -
CBPeripheral代表外设,通过didDiscoverServices回调处理服务
跨平台实现建议:
-
Flutter:
flutter_blue_plus已封装好权限和回调。 -
React Native:
react-native-ble-plx+react-native-permissions。 -
KMP:
kable提供协程友好的 API,无需处理复杂的回调地狱。
常见踩坑:
-
Android 某些机型上,
onConnectionStateChange回调可能不在主线程,更新 UI 需切线程。 -
BLE 连接后如果长时间不操作,部分手机会自动断开,需要定期发送空包保持连接。
-
写入特征值时,注意 MTU 大小(默认 23 字节,可通过
requestMtu协商更大值)。
3.2 广域网连接:MQTT 长连接
Android 集成步骤(使用 Eclipse Paho):
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
连接代码示例:
java
String broker = "tcp://your-mqtt-broker:1883";
String clientId = MqttClient.generateClientId();
MqttAndroidClient client = new MqttAndroidClient(context, broker, clientId);
MqttConnectOptions options = new MqttConnectOptions();
options.setKeepAliveInterval(60);
options.setAutomaticReconnect(true);
client.connect(options);
订阅与发布:
java
client.subscribe("sensor/temperature", 1); // QoS 1
client.publish("device/control", payload, 1, false);
踩坑与优化:
-
断线重连 :设置
setAutomaticReconnect(true)后,重连成功不会自动恢复订阅,必须在onConnectComplete回调中重新订阅。 -
心跳 :根据网络环境动态调整
keepAlive(默认 60 秒),弱网可适当增加。 -
SSL/TLS :生产环境必须使用
ssl://协议,并配置证书。 -
离线消息 :若设备离线时 App 发送控制指令,可让 Broker 开启持久会话(
cleanSession=false),设备上线后立即收到。
iOS 端推荐 :CocoaMQTT 库,用法与 Android 类似。
Broker 选型:
-
开发测试:
Mosquitto(单机) -
生产环境:
EMQX(支持百万连接,内置规则引擎)
四、上篇小结
上篇主要解决了物联网 App 开发的前半程:如何选择通信协议、如何搭建跨平台框架、如何实现设备连接(BLE 和 MQTT)。掌握了这些,你已经可以写出一个能扫描、连接设备并收发数据的 App 原型。下篇将深入数据采集、远程控制和完整实战案例。