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。

避坑指南: 如果设备使用2G/3G/4G蜂窝网络,或者NB-IoT,HTTP的头部开销会让你欲哭无泪。我曾经在一个燃气表项目中,因为用了HTTP上报,每月流量费比设备本身还贵。后来改成了CoAP,流量费直接降了80%。

那什么时候用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"
  }
}
小技巧: 每个控制指令都带上一个唯一的request_id。这样当设备执行完指令后,云端可以根据这个ID去重,防止重复执行。我在一个智能门锁项目里就遇到过,因为网络重试导致门锁连续开关了三次,业主差点投诉。

另外,接口设计上要注意幂等性。说白了就是同一个指令发两次,效果跟发一次一样。比如「设置温度为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,记录下已下载的偏移量。下次断网重连后,从断点处继续下载。嗯,这个方案救了我那个摄像头项目。

OTA升级的几个关键点:
  • 分片下载: 建议每片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吧。

下一章咱们聊聊这三种协议如何混合使用,构建一个真正能打的物联网架构。