简介
IBM于1999年发明了MQTT,主要用于物联网通讯。
其特点:
- 轻量级的 machine-to-machine 通信协议
- publish/subscribe模式
- 基于TCP/IP
- 支持QoS
- 适合于低带宽、不可靠连接、嵌入式设备、CPU内存资源紧张
- 是一种比较不错的Android消息推送方案
- FacebookMessenger采用了MQTT
- MQTT有可能成为物联网的重要协议
MQTT 架构:
图片来源:
http://www.csdn.net/article/2015-05-27/2824778-Surfing-in-IoT-MQTT
官网文档地址:
http://mqtt.org/documentation
MQTT3.1在线文档
http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html
PDF下载
http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/MQTT_V3.1_Protocol_Specific.pdf
三种服务质量:
- “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送
- “至少一次”,确保消息到达,但消息重复可能会发生
- “只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果
MQTT应用
- 已经有php,java,c,python,c#等多种协议的版本
- 已经有多种移动程序使用MQTT协议,如facebook messenger
协议
固定头部
第1个字节
Message Type
4bit,16种消息类型
CONNECT
TCP连接建立完毕后,Client向Server发出一个Request。
如果一段时间内接收不到Server的Response,则关闭socket,重新建立一个session连接。
如果一个ClientID已经与服务器连接,则持有同样ClientID的旧有连接必须由服务器关闭后,新建立才能建立。CONNACK
Server发出Response响应。
0x00 Connection Accepted
0x01 Connection Refused: unacceptable protocol version
0x02 Connection Refused: identifier rejected
0x03 Connection Refused: server unavailable
0x04 Connection Refused: bad user name or password
0x05 Connection Refused: not authorizedPUBLISH 发布消息
Client/Servier均可以进行PUBLISH。
publish message 应该包含一个TopicName(Subject/Channel),即订阅关键词。
关于Topic通配符
/:用来表示层次,比如a/b,a/b/c。
#:表示匹配>=0个层次,比如a/#就匹配a/,a/b,a/b/c。
单独的一个#表示匹配所有。
不允许 a#和a/#/c。
+:表示匹配一个层次,例如a/+匹配a/b,a/c,不匹配a/b/c。
单独的一个+是允许的,a+不允许,a/+/b不允许
PUBACK 发布消息后的确认
QoS=1时,Server向Client发布该确认(Client收到确认后删除),订阅者向Server发布确认。PUBREC / PUBREL / PUBCOMP
QoS=2时- Server->Client发布PUBREC(已收到);
- Client->Server发布PUBREL(已释放);
- Server->Client发布PUBCOMP(已完成),Client删除msg;
订阅者也会向Server发布类似过程确认。
PINGREQ / PINGRES 心跳
Client有责任发送KeepAliveTime时长告诉给Server。在一个时长内,发送PINGREQ,Server发送PINGRES确认。
Server在1.5个时长内未收到PINGREQ,就断开连接。
Client在1个时长内未收到PINGRES,断开连接。
一般来说,时长设置为几个分钟。最大18hours,0表示一直未断开。
DUP flag(打开标志)
保证消息可靠传输,默认为0,只占用一个字节。不能用于检测消息重复发送等。只适用于客户端或服务器端尝试重发PUBLISH, PUBREL, SUBSCRIBE 或 UNSUBSCRIBE消息,注意需要满足以下条件:
- 当QoS > 0
- 消息需要回复确认
此时,在可变头部需要包含消息ID。当值为1时,表示当前消息先前已经被传送过。
QoS 服务质量
RETAIN(保持)
仅针对PUBLISH消息
1:表示发送的消息需要一直持久保存(不受服务器重启影响),不但要发送给当前的订阅者,并且以后新来的订阅了此Topic name的订阅者会马上得到推送。
备注:新来乍到的订阅者,只会取出最新的一个RETAIN flag = 1的消息推送。
0:仅仅为当前订阅者推送此消息。
假如服务器收到一个空消息体(zero-length payload)、RETAIN = 1、已存在Topic name的PUBLISH消息,服务器可以删除掉对应的已被持久化的PUBLISH消息。
参考:
http://www.blogjava.net/yongboy/archive/2014/02/07/409587.html