2、通信协议基础:充电宝常用的MQTT协议、CoAP协议、HTTP协议简介、数据包结构解析

聊到充电宝的物联网通信,绕不开的就是协议选择。很多刚入行的朋友问我:「为什么充电宝不用HTTP,非要用MQTT?」

这个问题问得好。我当年刚接触物联网时也这么想——HTTP多成熟啊,现成的库一大堆。结果第一个项目就栽了跟头。嗯,今天咱们就把这三个协议掰开揉碎了讲清楚。

2.1 MQTT协议:物联网的「轻量级信使」

MQTT,全称Message Queuing Telemetry Transport。说白了,就是一个发布/订阅模式的消息协议。我习惯叫它「轻量级信使」。

为什么充电宝喜欢用MQTT?三个字:省流量、省电、实时性好。

核心特点:

  • 发布/订阅模型:设备不直接通信,通过Broker中转
  • 三种QoS等级:0(最多一次)、1(至少一次)、2(恰好一次)
  • 遗嘱消息:设备异常断开时,Broker自动发送预设消息
  • 保留消息:新订阅者上线就能拿到最新状态

我在项目中遇到过这样一个场景:充电宝上报电量时,用QoS 0就够了。为什么?因为电量数据是周期性上报的,丢一包无所谓,下一包马上就来。但如果是「归还确认」这种关键指令,我建议用QoS 1,确保服务器收到。

我的经验:充电宝心跳包建议30-60秒一次。太频繁费电,太慢容易掉线。我曾经调过一台设备,心跳设成5分钟,结果用户还了充电宝,后台10分钟后才更新状态——被投诉惨了。

MQTT数据包结构

MQTT的数据包很简洁。固定头部只有2个字节,可变头部和有效载荷看具体报文类型。

固定头部(2字节):
  Byte 1: 报文类型 + 标志位
  Byte 2: 剩余长度(可变长编码)

可变头部:协议名、协议级别、连接标志等
有效载荷:具体数据内容

举个例子,一个充电宝上报电量的MQTT报文,大概长这样:

主题:/charger/device/123456/status
载荷:{"battery":85,"temp":32.5,"status":"idle"}

你看,数据量很小。一个完整的MQTT连接报文,也就几十个字节。相比HTTP动不动几百字节的头部,优势太明显了。

2.2 CoAP协议:专为受限设备而生

CoAP,Constrained Application Protocol。名字就告诉你了——它是给资源受限的设备用的。

CoAP基于UDP,不是TCP。这一点很重要。为什么?因为UDP不需要三次握手,省掉了建立连接的开销。充电宝这种电池供电的设备,能省一点是一点。

CoAP vs MQTT:

特性 CoAP MQTT
传输层 UDP TCP
模型 请求/响应(类似HTTP) 发布/订阅
头部开销 4字节 2字节起
可靠性 CON/NON消息 QoS 0/1/2
适用场景 传感器数据采集 双向通信、指令下发

我个人习惯在充电宝的「低功耗模式」下用CoAP。比如充电宝在库房里待机时,每隔5分钟用CoAP上报一次位置和电量。这时候用MQTT反而浪费——TCP连接要保持,心跳包还得一直发。

注意:CoAP的可靠性靠CON消息的重传机制保证。如果网络丢包严重,重传次数会暴增。我曾经在信号差的停车场测试过,CoAP的重传次数从默认的4次调到了8次才稳定。这个坑,提前告诉大家。

CoAP数据包结构

CoAP报文格式(4字节固定头部):
  Ver(2bit)| T(2bit)| TKL(4bit)| Code(8bit)| Message ID(16bit)
  
  Ver: 版本号,目前固定01
  T: 消息类型(CON=0, NON=1, ACK=2, RST=3)
  TKL: Token长度
  Code: 请求方法(0.01=GET, 0.02=POST, 0.03=PUT, 0.04=DELETE)
  Message ID: 用于匹配请求和响应

你看,CoAP的头部才4个字节。对比HTTP动辄几十字节的头部,差距一目了然。

2.3 HTTP协议:老大哥的局限性

HTTP,不用多介绍了吧。互联网的基石。但在充电宝物联网场景里,它有点「水土不服」。

为什么?三个原因:

  • 头部太大:一个GET请求的头部可能200-300字节,充电宝上报一次电量才几十字节,效率太低
  • 连接开销:HTTP/1.1的短连接每次都要三次握手,长连接又需要保活
  • 实时性差:只能客户端主动请求,服务器不能主动推送

不过,HTTP也不是一无是处。充电宝的「固件升级」场景,我建议用HTTP。为什么?因为固件包大,HTTP的分块传输、断点续传功能很成熟。MQTT传大文件?那得把人急死。

我的建议:充电宝的日常通信用MQTT,固件升级用HTTP,低功耗待机用CoAP。三种协议各司其职,别指望一个协议打天下。

HTTP数据包结构

HTTP请求报文:
  GET /api/charger/status HTTP/1.1
  Host: cloud.example.com
  User-Agent: Charger/1.0
  Accept: application/json
  
HTTP响应报文:
  HTTP/1.1 200 OK
  Content-Type: application/json
  Content-Length: 45
  
  {"battery":85,"status":"idle"}

看到了吧?光头部就占了七八行。充电宝每次上报都带这么多冗余信息,流量费扛不住啊。

2.4 协议选择实战指南

讲了这么多理论,咱们来点实际的。充电宝项目到底怎么选协议?

我的选型原则:

  1. 实时指令下发:MQTT(QoS 1或2)
  2. 周期性数据上报:MQTT(QoS 0)或CoAP(NON消息)
  3. 固件升级:HTTP(分块传输)
  4. 低功耗待机:CoAP(CON消息,带重传)
  5. 设备注册/认证:HTTP(一次性的,不频繁)

我记得有个项目,客户非要全部用HTTP。结果呢?一台充电宝一天产生2MB流量,1000台设备一个月流量费好几万。后来改成MQTT,流量降到原来的十分之一。老板脸都笑开了花。

避坑指南:我曾经遇到过充电宝在弱网环境下,MQTT频繁重连导致电池耗光的问题。后来加了「指数退避」策略——第一次重连等1秒,第二次2秒,第三次4秒...最多等5分钟。效果立竿见影。

好了,协议基础就讲到这里。下一章咱们聊聊充电宝物联网卡的APN配置和网络附着流程。那个坑更多,我到时候一个个给你们拆解。