MQTT V3.1----flow
该文章转自:聂永的博客(http://www.blogjava.net/yongboy/archive/2014/02/15/409893.html)
网络故障
在任何网络环境下,都会出现一方连接失败,比如离开公司大门那一刻没有了WIFI信号。但持续连接的另一端-服务器可能不能立即知道对方已断开。类似网络异常情况,都有可能在消息发送的过程中出现,消息发送出去,就丢失了。
MQTT协议假定客户端和服务器端稳定情况一般,彼此之通信管道不可靠,一旦客户端网络断开,情况就会很严重,很难恢复原状。
但别忘记,很多客户端会有永久性存储设备支持,比如闪存ROM、存储卡等,在通信出现异常的情况下可以用于保存关键数据或状态信息等。
总之,异常网络情况很复杂,只能小心处理之。
消息重发策略
在QoS > 0情况下,PUBLISH、PUBREL、SUBSCRIBE、UNSUBSCRIBE等类型消息在发送者发送完之后,需要等待一个响应消息,若在一个指定时间段内没有收到,发送者可能需要重试。重发的消息,要求DUP标记要设置为1.
等待响应的超时应该在消息成功发送之后开始算起,并且等待超时应该是可以配置选项,以便在下一次重试的时候,适当加大。比如第一次重试超时10秒,下一次可能为20秒,再一次重试可能为60秒呢。当然,还要有一个重试次数限制的。
还 有一种情况,客户端重新连接,但未在可变头部中设置clean session标记,但双方(客户端和服务器端)都应该重试先前未发送的动态消息(in-flight messages)。客户端不被强制要求发送未被确认的消息,但服务器端就得需要重发那些未被去确认的消息。
QoS level决定的消息流
QoS level为Quality of Service level的缩写,翻译成中文,服务质量等级。
MQTT 3.1协议在"4.1 Quality of Service levels and flows"章节中,仅仅讨论了客户端到服务器的发布流程,不太完整。因为决定消息到达率,能够提升发送质量的,应该是服务器发布PUBLISH消息到订阅者这一消息流方向。
QoS level 0
至多发送一次,发送即丢弃。没有确认消息,也不知道对方是否收到。
Client
| Server | ||
|---|---|---|
| QoS = 0 | PUBLISH ----------> |
Action: Publish message to subscribers then Forget Reception: <=1 |
针对的消息不重要,丢失也无所谓。
网络层面,传输压力小。
QoS level 1
所有QoS level 1都要在可变头部中附加一个16位的消息ID。
SUBSCRIBE和UNSUBSCRIBE消息使用QoS level 1。
针对消息的发布,Qos level 1,意味着消息至少被传输一次。
发送者若在一段时间内接收不到PUBACK消息,发送者需要打开DUB标记为1,然后重新发送PUBLISH消息。因此会导致接收方可能会收到两次PUBLISH消息。针对客户端发布消息到服务器的消息流:
Client
| Server | ||
|---|---|---|
| QoS = 1 DUP = 0 Message ID = x Action: Store message |
PUBLISH ----------> |
Actions:
Reception: >=1
|
| Action: Discard message | PUBACK <---------- |
Message ID = x
|
针对服务器发布到订阅者的消息流:
Server
| Subscriber | ||
|---|---|---|
| QoS = 1 DUP = 0 Message ID = x |
PUBLISH ----------> |
Actions:
Reception: >=1
|
PUBACK <---------- |
Message ID = x
|
发
布者(客户端/服务器)若因种种异常接收不到PUBACK消息,会再次重新发送PUBLISH消息,同时设置DUP标记为1。接收者以服务器为例,这可能
会导致服务器收到重复消息,按照流程,broker(服务器)发布消息到订阅者(会导致订阅者接收到重复消息),然后发送一条PUBACK确认消息到发布
者。
在业务层面,或许可以弥补MQTT协议的不足之处:重试的消息ID一定要一致接收方一定判断当前接收的消息ID是否已经接受过
但一样不能够完全确保,消息一定到达了。
QoS level 2
仅仅在PUBLISH类型消息中出现,要求在可变头部中要附加消息ID。
级别高,通信压力稍大些,但确保了仅仅传输接收一次。
先看协议中流程图,Client -> Server方向,会有一个总体印象:
Client
| Server | ||
|---|---|---|
| QoS = 2 DUP = 0 Message ID = x Action: Store message |
PUBLISH ----------> |
Action(a) Store message
or Actions(b):
|
PUBREC <---------- |
Message ID = x | |
| Message ID = x | PUBREL ----------> |
Actions(a):
or Action(b): Delete message ID |
| Action: Discard message | PUBCOMP <---------- |
Message ID = x |
Server -> Subscriber:
Server
| Subscriber | ||
|---|---|---|
| QoS = 2 DUP = 0 Message ID = x |
PUBLISH ----------> |
Action: Store message |
PUBREC <---------- |
Message ID = x | |
| Message ID = x | PUBREL ----------> |
Actions:
|
PUBCOMP <---------- |
Message ID = x |
Server
端采取的方案a和b,都包含了何时消息有效,何时处理消息。两个方案二选一,Server端自己决定。但无论死采取哪一种方式,都是在QoS level
2协议范畴下,不受影响。若一方没有接收到对应的确认消息,会从最近一次需要确认的消息重试,以便整个(QoS level 2)流程打通。
消息顺序
消息顺序会受许多因素的影响,但对于服务器程序,必须保证消息传递流程的每个阶段要和开始的顺序一致。例如,在QoS level 2定义的消息流中,PUBREL流必须和PUBLISH流具有相同的顺序发送:
Client
| Server | ||
|---|---|---|
PUBLISH 1---------->PUBLISH 2 ---------->PUBLISH 3 ----------> |
||
PUBREC 1<----------PUBREC 2 <---------- |
||
PUBREL 1----------> |
||
PUBREC 3<---------- |
||
PUBREL 2----------> |
||
PUBCOMP 1<---------- |
||
PUBREL 3----------> |
||
PUBCOMP 2<----------PUBCOMP 3 <---------- |
流动消息(in-flight messages)数量允许有一个可保证的效果:
- 在流动消息(in-flight)窗口1中,每个传递流在下一个流开始之前完成。这保证消息以提交的顺序传递
- 在流动消息(in-flight)大于1的窗口,只能在QoS level内被保证消息的顺序
消息的持久化
在MQTT协议中,PUBLISH消息固定头部RETAIN标记,只有为1才要求服务器需要持久保存此消息,除非新的PUBLISH覆盖。
对于持久的、最新一条PUBLISH消息,服务器不但要发送给当前的订阅者,并且新的订阅者(new subscriber,同样需要订阅了此消息对应的Topic name)会马上得到推送。
Tip:新来乍到的订阅者,只会取出最新的一个RETAIN flag = 1的消息推送,不是所有。
小结
mqtt的消息流,以小和轻量为主要目标,QoS级别进行了消息传输的保证。
MQTT V3.1----flow的更多相关文章
- MQTT V3.1--我的理解
最近因为工作需要,需要对推送消息了解,因此对MQTT进行了整理,这里更多的是对MQTT英文版的翻译和理解. MQTT(Message Queue Telemetry Transport),遥测传输协议 ...
- MQTT V3.1----publish解读
客户端/服务器的发布消息行为,与PUBLISH相关的消息类型: PUBLISH 客户端发布消息经由服务器分发到所有对应的订阅者那里.一个订阅者可以订阅若干个主题(Topic name),但一个PUBL ...
- TCP/IP, WebSocket 和 MQTT
按照OSI网络分层模型,IP是网络层协议,TCP是传输层协议,而HTTP和MQTT是应用层的协议.在这三者之间, TCP是HTTP和MQTT底层的协议.大家对HTTP很熟悉,这里简要介绍下MQTT.M ...
- Android开发笔记之《远程控制(MQTT|mosquitto) && (ProtocalBuffer | GRPC)》
Android推送方案分析(MQTT/XMPP/GCM): http://www.open-open.com/lib/view/open1410848945601.htmlMQTT官网: http:/ ...
- MQTT(二)推送
MQTT V3.1----publish解读 - leeying - 博客园 http://www.cnblogs.com/leeying/p/3791341.html MQTT - 聂永的博客 - ...
- MQTT协议(一)
MQTT(Message Queue Telemetry Transport),遥测传输协议,提供订阅/发布模式,更为简约.轻量,易于使用,针对受限环境(带宽低.网络延迟高.网络通信不稳定),可以简单 ...
- MQTT服务器搭建-mosquitto1.4.4安装指南
Mosquitto mosquitto是一款实现了 MQTT v3.1 协议的开源的消息代理服务软件. 其提供了非常轻量级的消息数据传输协议,采用发布/订阅模式进行工作,可用于物联设备.中间件.APP ...
- MQTT——安装、测试
MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用 http://blog.csdn.net/xukai871105/article/details/39252653 ...
- 【转载】MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用
http://blog.csdn.net/xukai871105/article/details/39252653 0 前言 MQTT是IBM开发的一个即时通讯协议.MQTT是面向M2M和物联 ...
随机推荐
- java中关于正则一些基础使用
希望能帮到有需要的朋友.-----转载请注明出处. 对于正则处理相关的知识,我一开始是从网上找资料配合使用Java API1.6的一个中文版进行学习,很感谢翻译这个版本的团队(机构)或者个人,很感谢那 ...
- .Net判断一个对象是否为数值类型探讨总结(高营养含量,含最终代码及跑分)
前一篇发出来后引发了积极的探讨,起到了抛砖引玉效果,感谢大家参与. 吐槽一下:这个问题比其看起来要难得多得多啊. 大家的讨论最终还是没有一个完全正确的答案,不过我根据讨论结果总结了一个差不多算是最终版 ...
- PHP与memcache安装使用说明
最近网站流量上来后,数据库连接数一直偏高,分析了下,都是正常请求,只是网站功能分的细,单页面数据库查询句偏多了,很多数据是没必要实时查询,缓存起来就可以的!考虑必须用memcache缓存了,减轻mys ...
- Jackson fasterxml跟codehaus的区别 (fasterxml vs. codehaus) -- 转载
Jackson fasterxml和codehaus的区别: 他们是Jackson的两大分支.也是两个版本的不同包名.Jackson从2.0开始改用新的包名fasterxml:1.x版本的包名是cod ...
- android应用中增加权限判断
android6.0系统允许用户管理应用权限,可以关闭/打开权限. 所以需要在APP中增加权限判断,以免用户关闭相应权限后,APP运行异常. 以MMS为例,在系统设置——应用——MMS——权限——&g ...
- win7 64的系统安装。net4.0总是提示安装未成功
主要原因是Windows update的临时文件损坏,建议重命名该文件夹. 1. 开始——运行——cmd——键入net stop WuAuServ回车(停止windows update服务): 2. ...
- 在 iTunes content中创建新的版本时,出现构建版本后面没有加号。
老项目升级时,提交版本时,ipa已经上传成功到APP store,但是构建版本后面一直都没有加号,等了一夜还是没有反应 后来苹果发来一封邮件,意思是,我需要在plist文件中添加一个NSMicroph ...
- JAVA求圆的面积
import java.text.DecimalFormat;import java.util.Scanner; public class TheAreaOfCircle { public stati ...
- Tomcat服务器8080端口占用报错
报错信息如下: Oct , :: PM org.apache.coyote.AbstractProtocol init SEVERE: Failed to initialize end point a ...
- 开园第一篇 - 论移动开发环境 IOS与Android的差异
首先,在真正写技术之前做个自我简介.本人08年开始学c语言 一年后,转vc++.开始接触MFC MFC做了两年.转眼11年了我考上了一个不知名的大专.搞C++发现没有市场了因为当时酷狗腾讯的软件已经日 ...