MQTT简单了解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aiwusheng/article/details/79400230

MQTT简单了解

参考

百度百科:MQTT协议
MQTT协议-MQTT协议简介及协议原理
MQTT入门篇
MQTT与TCP的关系
MQTT数据包结构
MQTT英文文档 Version 3.1.1
MQTT协议中文版翻译

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的 “轻量级” 通讯协议。

  • 该协议构建于TCP/IP协议上,由IBM在1999年发布。
  • MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。做为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用
  • 通过MQTT协议,目前已经扩展出了数十个MQTT服务器端程序,可以通过PHP,JAVA,Python,C,C#等系统语言来向MQTT发送相关消息
  • 国内很多企业都广泛使用MQTT作为Android手机客户端与服务器端推送消息的协议。其中Sohu,Cmstop手机客户端中均有使用到MQTT作为消息推送消息。

为什么要在 TCP 协议之上再封装一层 MQTT 协议呢?

为什么要在 TCP 协议之上再封装一层 MQTT 协议呢?
举个例子,如果你要用 TCP 协议做一个即时聊天室,那么:

  • 首先需要写一个服务器程序,监听某个端口,这样客户端就能连接上来了。然后大家就能向该服务器发送数据了。
  • 但是我们并不希望随便谁都能连接该服务器,并且向其发送消息,于是需要一个注册页面,让别人先去注册账号,然后客户端创建连接时发送的第一个TCP报文必须包含了 “账号” “密码”。这样当服务端收到第一个报文之后,就能判断这个连接是否合法了。
  • 对于发送过来的“账号”“密码”做如下约定:
    第一个字节为1 (CONNECT客户端请求连接到服务器),用来告诉服务端这是一个请求连接的报文;
    第二个字节是报文剩下的长度;
    然后就是 “MQTT” 协议名,后面紧跟着就是账号,然后是密码。
  • 对于账号的长度:
    账号第一个字节是账号的长度,剩下才是账号内容,这样就解决了“账号有多长”的问题了,密码同理。
    如果账号密码不匹配就断开连接并且返回一句“xxxx off”,如果创建连接后半天不发送任何东西也断开连接。
  • 现在大家的客户端都连接上来了,服务端保存了一个账号:socket的map,能通过任何一个账号找到这个人的socket并向他发送信息。接下来大家要开始聊天了。
  • 在聊天室中,一个客户端发送的消息其他客户端都能收到。用户首先去web页面创建聊天室,然后会得到一个聊天室的ID。
    然后用户要加入聊天室,必须先发送一个加入聊天室的报文。然后你要求报文第一个字节为8(SUBSCRIBE客户端订阅请求)代表加入聊天室的请求报文,然后是报文剩余长度,然后是聊天室ID。
  • 现在有多个用户加入了聊天室,其中每个用户又都加入了多个聊天室。
  • 假设现在大家在聊天室A中开始聊天。用户甲向服务器发送消息,约定:
    发送消息的报文的第一个字节为3(PUBLISH发布消息)
    第二个字节是报文剩下的长度;
    然后就是 “MQTT” 协议名,跟聊天室ID;
    最后是具体的消息内容。
  • 服务器收到第一个字节为3的消息,就知道这是一个聊天消息。然后根据上面带的聊天室ID以及你在服务器存储的用户和聊天室的关系,找到了这个聊天室里的所有人,然后你就把消息发给这里面的所有人了。

上面这个例子,在连接服务器(检查合法性、断开连接)、订阅主题(加入聊天室)、发布消息这些过程中,约定的报文格式和设计的服务器处理逻辑就是 MQTT 协议的内容。
当前相比于真正的MQTT协议,这个例子非常不完善。对于完整的MQTT协议还需查看MQTT协议中文版翻译

服务质量

为了满足不同的场景,MQTT支持三种不同级别的服务质量(Quality of Service,QoS)为不同场景提供消息可靠性:

  • 级别0:尽力而为。消息发送者会想尽办法发送消息,但是遇到意外并不会重试。
  • 级别1:至少一次。消息接收者如果没有知会或者知会本身丢失,消息发送者会再次发送以保证消息接收者至少会收到一次,当然可能造成重复消息。
  • 级别2:恰好一次。保证这种语义肯定会减少并发或者增加延时,不过丢失或者重复消息是不可接受的时候,级别2是最合适的。

级别2所提供的不重不丢很多情况下是最理想的,不过往返多次的确认一定对并发和延迟带来影响。
级别1提供的至少一次语义在日志处理这种场景下是完全OK的,所以像Kafka这类的系统利用这一特点减少确认从而大大提高了并发。
级别0适合鸡肋数据场景,食之无味弃之可惜,就这么着吧。

MQTT控制报文的类型

MQTT拥有14种不同的控制报文的消息类型:

报文类型 Value 报文流动方向 详细描述
CONNECT 1 客户端到服务端 客户端请求连接服务端
CONNACK 2 服务端到客户端 连接报文确认
PUBLISH 3 两个方向都允许 发布消息
PUBACK 4 两个方向都允许 QoS 1消息发布收到确认
PUBREC 5 两个方向都允许 发布收到(保证交付第一步)
PUBREL 6 两个方向都允许 发布释放(保证交付第二步)
PUBCOMP 7 两个方向都允许 QoS 2消息发布完成(保证交互第三步)
SUBSCRIBE 8 客户端到服务端 客户端订阅请求
SUBACK 9 服务端到客户端 订阅请求报文确认
UNSUBSCRIBE 10 客户端到服务端 客户端取消订阅请求
UNSUBACK 11 服务端到客户端 取消订阅报文确认
PINGREQ 12 客户端到服务端 心跳请求
PINGRESP 13 服务端到客户端 心跳响应
DISCONNECT 14 客户端到服务端 客户端断开连接

MQTT数据包结构

详细查看:

MQTT数据包结构
MQTT协议中文版翻译

阅读更多

扫码向博主提问

xiaxl

博客专家

android、opengl es相关
  • 擅长领域:
  • android
  • opengl es
去开通我的Chat快问

没有更多推荐了,返回首页