3、HTTP在物联网中的实践:设备状态上报、远程控制接口、文件OTA升级
聊完了MQTT和CoAP,咱们来看看HTTP。很多人一提到物联网,第一反应就是「HTTP太重了,不适合嵌入式设备」。这话有一定道理,但也不全对。
我个人的习惯是:在设备端尽量少用HTTP,但在云端和App端,HTTP几乎是绕不开的。你想想看,现在哪个智能家居App不是通过RESTful API跟云平台通信的?设备状态查询、远程控制指令下发、固件升级包下载……这些场景里,HTTP依然扮演着重要角色。
3.1 设备状态上报:用POST还是PUT?
先说最常见的场景——设备往云端上报状态。比如一个温湿度传感器,每隔5分钟上报一次温度和湿度数据。
这里有个经典问题:用POST还是PUT?
我记得刚入行那会儿,有个项目里团队争论了好久。后来我总结了一个简单原则:
- 如果服务端负责生成资源ID(比如设备第一次注册,云端返回一个设备ID),用POST
- 如果客户端自己知道资源ID(比如设备SN号就是唯一标识),用PUT
对于设备状态上报,我建议用PUT。因为每个设备都有唯一的标识(比如IMEI或MAC地址),你直接往 /devices/{deviceId}/status 这个路径上PUT数据,语义清晰,也符合RESTful规范。
来看一个实际例子:
PUT /api/v1/devices/SN20240315001/status HTTP/1.1
Host: iot.example.com
Content-Type: application/json
Authorization: Bearer <token>
{
"temperature": 25.6,
"humidity": 68.3,
"battery": 85,
"timestamp": "2024-03-15T10:30:00Z"
}
这里有个坑——HTTP请求头太大了。一个POST/PUT请求,光Header就得几百字节,而实际数据可能才几十字节。我曾经在一个NB-IoT项目里吃过这个亏,设备每次上报光HTTP头部就占了70%的流量,气得我直接换成了CoAP。
那什么时候用HTTP上报合适?我个人觉得:
- 设备有WiFi或有线网络,带宽充足
- 上报频率低(比如每小时一次)
- 需要跟现有Web系统无缝对接
3.2 远程控制接口:RESTful API的设计要点
远程控制是物联网的核心功能之一。用户通过App点一下「开灯」,这个指令怎么传到设备上?
这里我推荐用异步控制模式。什么意思呢?App发一个POST请求到云端,云端返回202 Accepted,表示「指令已收到,正在下发」。设备收到指令后,再通过MQTT或CoAP把执行结果回传给云端。
为什么不用同步?你想想看,如果设备在深山里,网络延迟好几秒,App一直转圈等响应,用户体验得多差。
来看一个典型的远程控制接口设计:
POST /api/v1/devices/SN20240315001/commands HTTP/1.1
Host: iot.example.com
Content-Type: application/json
Authorization: Bearer <token>
{
"command": "set_switch",
"params": {
"channel": 1,
"value": true
},
"request_id": "cmd_20240315103000_001"
}
返回结果:
HTTP/1.1 202 Accepted
Content-Type: application/json
{
"code": 0,
"message": "command accepted",
"data": {
"request_id": "cmd_20240315103000_001",
"status": "pending"
}
}
另外,接口设计上要注意幂等性。说白了就是同一个指令发两次,效果跟发一次一样。比如「设置温度为26度」,发一次和发十次,最终温度都是26度。但「温度+1度」这种就不幂等,发两次就变成28度了。
3.3 文件OTA升级:大文件传输的挑战
OTA升级是物联网里最头疼的事情之一。一个固件包少则几百KB,多则几十MB,用HTTP传大文件,问题就来了。
我经历过最惨的一次:一个智能摄像头项目,固件包15MB,设备通过WiFi下载。结果有10%的设备下载到一半网络断了,重新下载又得从头开始。用户家里的流量哗哗地跑,投诉电话打爆了。
所以,断点续传是OTA升级的刚需。HTTP/1.1的Range头就是干这个的:
GET /firmware/v2.3.1/camera_fw.bin HTTP/1.1
Host: ota.example.com
Range: bytes=1048576-2097151
服务端返回:
HTTP/1.1 206 Partial Content
Content-Range: bytes 1048576-2097151/15728640
Content-Length: 1048576
设备每次下载1MB,记录下已下载的偏移量。下次断网重连后,从断点处继续下载。嗯,这个方案救了我那个摄像头项目。
- 分片下载: 建议每片256KB~1MB,太大容易超时,太小HTTP请求太多
- MD5校验: 每片下载完校验一次,全部下载完再校验整个文件
- 版本回退: 升级失败后能回退到旧版本,别让设备变砖
- 灰度发布: 先升级10%的设备,观察没问题再全量推送
还有一个容易被忽略的问题——并发下载。如果同时有10万台设备请求OTA升级,CDN扛得住吗?我建议用P2P分发或者分级下发的策略。比如先升级10台边缘网关,再由网关给子设备分发固件。
3.4 HTTP在物联网中的优缺点总结
| 场景 | 推荐用HTTP吗? | 原因 |
|---|---|---|
| 设备状态上报(高频) | ❌ 不推荐 | 头部开销大,建议用MQTT或CoAP |
| 设备状态上报(低频) | ✅ 可用 | 开发简单,跟Web系统无缝对接 |
| App远程控制 | ✅ 推荐 | RESTful API成熟,生态好 |
| 文件OTA升级 | ✅ 推荐 | 支持断点续传,CDN加速方便 |
| 实时数据流 | ❌ 不推荐 | WebSocket或MQTT更合适 |
最后说一句:不要试图用HTTP解决所有问题。我在一个智慧农业项目里,看到有人用HTTP做传感器数据实时推送,结果服务器连接数爆了。后来改成MQTT,世界清净了。
HTTP在物联网里的定位,说白了就是「管理面」——设备注册、状态查询、远程控制、OTA升级。而「数据面」——高频数据上报、实时控制指令,还是交给MQTT或CoAP吧。
下一章咱们聊聊这三种协议如何混合使用,构建一个真正能打的物联网架构。