C语言复健记录三: MQTT协议

简介

MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议,它的设计思想是轻巧、开放、简单、规范,易于实现。这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器的通信(M2M)以及物联网环境(IoT).

MQTT特性

MQTT在设计之初便确认了以下特性:

  • 精简,功能和数据两个方面
  • 发布/订阅模式,针对一对多
  • 应对糟糕的网络环境
  • 客户端计算能力较低

MQTT机制

订阅/发布机制

MQTT最重要的机制是订阅/发布机制,客户端连接 Broker 订阅 topic 来进行数据传输.

消息类型

MQTT协议包括14种不通的消息类型,可以通过报文中固定报文的第一个字节进行筛选.

遗愿机制

MQTT协议通过遗愿机制来应对糟糕的网络环境以及不稳定的客户端,当客户端与服务器出现故障时,服务端会根据上一条报文的遗愿消息进行发布,一般发布的条件包括且不限于:

  • 服务端检测到了一个I/O错误或者网络故障
  • 客户端在心跳时间(Keep Alive)内未能通信
  • 客户端在未发送正常关闭(0x00)的情况下关闭了网络连接
  • 服务端在没有收到正常关闭(0x00)的情况下关闭了网络链接

这样,当客户端故障的情况下,服务端可以进行后续处理,同时通知用户,而不需要长时间保持连接浪费系统资源.

心跳机制
  • 心跳机制(Keep Alive)用双字节整数来表示以秒位单位的时间间隔. 它表示在客户端传输完成一个MQTT控制报文的时刻到下一个报文发送时刻所允许空闲的最大时间间隔.客户端负责保证两条报文之间的发送间隔不得超过心跳间隔.

  • 如果没有信息需要发送, 至少且必须发送一个PINGREQ报文来通知服务端保持连接. 客户端可以随时发送PINGREQ报文, 并且可以使用PINGRESP报文判断网络和服务端的活动状态.

  • 如果心跳间隔非零, 且服务端在1.5T的时间内没有收到客户端的控制报文, 则会关闭客户端的网络连接, 且判断网络连接以断开.

  • 如果客户端发送了PINGREQ报文之后, 在一定时间内没有收到PINGRESP报文, 则客户端应该关闭到服务端的网络连接.

  • 心跳间隔(Keep Alive)的值为零时,表示关闭心跳机制,客户端不必按特定时间发送MQTT控制报文.

消息质量(QoS)

消息质量同样是用来消息质量(QOS)分为三种等级:

  • QOS=0,表示最多分发一次,不保证消息到达,可能会丢失或者重复,服务端不会返回确认消息
  • QoS=1,表示至少分发一次,保证消息到达,但是可能会有重复,服务端需要返回确认消息PUBACK
  • QoS=2,只分发一次,保证消息到达并且只有一次

MQTT协议内容

详细协议内容可参考 MQTT协议.

MQTT报文格式

MQTT报文由三部分组成:

  • 固定报头(必需)
  • 可变报头(可选)
  • 有效载荷(可选)
固定报头

固定报头里包含当前报文的类型和报文长度:

位置功能
byte 1报文类型+标志位
byte 2剩余报文长度(可变)
可变报头

可变报头包含报文标识符属性.
报文标识符只存在于部分类型的MQTT报文中,占2个字节.
属性字段由属性长度和所有属性组成.

  • 属性长度不包含自身长度,只是用于声明所有属性的长度,如果没有任何属性,则必须由属性长度位0的字段来指示.
  • 属性由一段数据和一个定义了属性用途和数据类型的标识符组成.
有效载荷

一般为消息内容.每一种类型的报文都不一样,详见文档.

原因码

原因码是一个单字节无符号数,用来指示一次操作的结果. 小于0x80的原因码表示操作成功,大于等于0x80的原因码表示操作失败.

常用客户端

MQTT是多并发高连接数的一种通信协议, 常用的有:

  • Mosquitto (C/C++)
  • VerneMQ (ERLANG)
  • EMQTT(ERLANG)
  • ActiveMQ(Java)
  • Mosca(Node.js)
Mosquitto

官方下载mosquitto可以直接进行测试,在配置文件中有详细配置,另外有库文件paho可以直接进行二次开发,里面有详细例程.
具体测试等有想搞得东西在搞…反正测试的也都差不多了…

EMQTT

EMQTT是国产的开源代码,用的erlang/otp写的,服务端可以直接下载使用,详细教程网上很多.
MQTT的协议格式都是标准的, 客户端语言支持多种语言.

MQTT应用的一些细节

流量相关

MQTT相对于其他的HTTP/TCP之类的来说流量的开销是最小的
tls加密会在设备和平台每次发包前加大概30字节的数据(应该是证书,具体没去确认)
keepalive的过程分为三个过程,会发三个数据包,大小大约是 54 54 60字节,如果启用了tls加密 就是84 84 60这样

mqtt的流量消耗的大体概念是 mqtt平台和设备只建立连接,5分钟的保活间隔,那么一个月大概会走6/8Mb的流量(后面是tls的数据)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值