MQTT——发布报文
发布报文的知识点并不难,只是多。看过前面几章的读者们应该或多或少都认识服务质量QOS。发布报文跟他的联系最紧的。我们也清楚订阅报文里面虽然也有用到QOS,但是他却没有更进一步的联系。往下看就知道是什么一会事了。
服务质量QOS
不管是订阅报文还是发布报文都会遇到一个问题——报文流失的问题。所以才会有了服务质量这一说法(个人看法)。什么意思呢?就是用来处理流失的问题。即然报文在发送的过程中可能存在流失的问题。那么最直接的决解方案就是重新发送,不就行了吗。所以服务质量事实就是在表示报文要分送几次。QOS有三个值。分别表示着三种不同的处理报文方式。相应的值如下
QOS 0:最多分发一次。即是可以零次或是一次。不过笔者认零次的情况大多数是不可能存在的。一次到很常见。
QOS 1:至少分发一次。
QOS 2:只分发一次。
笔者在看MQTT协议文档的时候,对于QOS的分发一直有一个小问题。笔者以为是指客户端到客户端的分发。不过看了几遍觉得他是指客户端到服务端的分发。那么为什么笔者会认为是客户端到客户端的分发呢?主要是笔者认为QOS是指报文到客户端的次数。比如QOS 1说明分送到每一个符合客户端的报文至少一次。所以才会有至少分送一次的说法。原来一开始笔者理解错了。所以请记住这里服务质量QOS是指客户端与服务端的分发。所谓的分发- 次,至少一次,更不是指报文到客户端的次数。
如果分发是客户端到服务端的话。假设服务端收到了QOS 1的报文。那么服务端就会回发一个响应表示收到,QOS 1的处理就这样子结束了。而服务端还要把这个报文发送到别的符合的客户端。这个时候还是存在的报文流失的问题。你们也清楚网络有时候就是这样子。当然这个可能笔者多虑了。但是服务质量QOS就是把相关的报文不停的重发。那么对于重数的次数MQTT肯定不可能不做一些记录。所以固定报头的DUP作用就出来了。重发一次就把DUP加1。下面笔者会细说。
服务质量QOS 0 笔者喜欢用一词来形客。管杀不管埋。发出去之后。收不收的到不管了。当然笔者说的有一点过头了。这里是指客户端向服务端发送发布报文,只要服务端接收到了。那么客户端就在也不管了。
服务质量QOS 1的要求是至少分发一次。如果失败的话就一直重复分发。笔者先把流程写出来。然后加一张图来加深理解。
1)客户端向服务端发起一个发布报文。如果服务端没有接到。请你继续起发不用客气。
2)服务端收到一个来看客户端的发布报文。查看一下原来是服务质量QOS为1的报文。服务端就必须回发一个叫发布确认(PUBACK)的报文。而这个时候客户端也在等待着服务端的回应(好了故事就从这里开始了)。
3)客户端等了一段时间就是没有接到来自服务端的回应,没有办法客户端只能认为失败了。在重发一次吧。这个时候客户端就必须把固定报头里面的DUP加1了。但是服务端事实上没有问题,并且开始给符合主题的客户端们发分信息了。只是可能这一段时间正在处理一些事情,回应慢了。
4)客户端终于接收到了回应(PUBACK)。结束了。
注意:图片中的红线就是一个重发的环。
从上面的流程我们就可以看出来一个问题,服务端有可能收到多次的发布报文。那么当服务端在次接收到DUP大于0的报文,不管他,当前普通的报文一样了处理。同样子也要给客户端一个回应,不然他又要重发了。那么这就意味着服务端要处理相同的发布报文问题。可惜文档里面要求当作正常的报文来处理就行了。即是不管是不是重发的报文,只要接到报文并且他的QOS大于0,那么给对应的客户端一个回应。同时给符合主题的客户端们分发报文。显然客户端们会接收到多个相同的信息了。
服务质量QOS 2表示只分发一次。 笔者在看文档MQTT 3.1里面的QOS2 处理时候,有一点不理解。后来在去看一下MQTT 3.1.1果然写的清楚一点了。不然笔者以为跟服务质量QOS 1没有什么区别。让我们看一下他是什么处理才只分一次呢?
1)客户端向服务端发起一个发布报文。如果服务端没有接到。请你继续起发不用客气。
2)服务端收到一个来看客户端的发布报文。查看一下原来是服务质量QOS为2的报文。服务端处理相关操作之后,就回应一个叫PUBREC 的报文。如果是服务质量QOS 1的话,这个时候会给符合的客户端们发送信息。那么服务质量QOS 2这边要不要这个时候给符合主题的客户端们发送信息呢?当然这一点档文也没有特别指出来。所以笔者认为应该是可以的。同时服务端还要等待来自客户端的一个叫PUBREL的报文呢?
3)客户端在一段时间之后,如果没有收到相关回应的话,重发一次,同时DUP加1。直到接收到回应(PUBREC)。
4)当前客户端接收到了来自服务端的回应(PUBREC)。客户端就必须在回头跟服务端说一声:“我收到你的回应了”。因为服务端一直在等客户端的回应,即是PUBREL报文。如果客户端一直不给服务端回发一个回应,表示客户端已经收到回应。服务端会一直重发PUBREC。这个时候DUP有没有加1。文档里面没有说明。所以应该是不需要。直到服务端接收到客户端的回应(PUBREL)。在笔者心里面这里才是给符合主题的客户端们发送信息的时候。
5)客户端在给服务端发送PUBREL报文,说明我收到了你的回应了。同时客户端又在等待服务端的另一个回应。告诉客户端动作结束了。即是PUBCOMP报文。
6)客户端收到来自服务端的PUBCOMP报文响应。结束了。
注意:图片中的红线就是一个重发的环。
理论上来讲服务质量QOS 2的安全等级绝对高于服务质量QOS 1。关是步棸QOS 2就比QOS1多了二步。而且这二步都是一个重发的环。图片中我们可以看到。可是如果细想一下,笔者心里面有一点不理解。所谓的至少分一次,只分发一次好像并没有体现出来。如QOS 2里面客户端没有接到PUBREC的报文时候,不是还是要重发一下发布报文。那么所以只分发一次。理解上就有一点怪怪的。笔者也想过可能QOS 2会根据消息ID特别处理报文,让同一个报文只处理一次。不然的话,不是还是会出现QOS 1那样子客户端们可能会收到重复的信息。可是笔者在MQTT 文档里面没有找到。这一点读者们自行去查看吧。
不管是QOS 1还是QOS 2。最后都要给符合主题的客户端发送信息。那么关键点是在什么时候发送。虽然文档里面有指出可以在PUBACK或是PUBREC之后就可以给符合主题的客户端发送信息。总之笔者没有找到特别指出的地方。所以大部分都是网络说的。QOS 1在PUBACK发出之后就可以发送给客户端信息。QOS 2在服务端接受PUBREL之后发送给客户端信息。当然读者们也可以自行选择吧。
发布报文结构
发布报文的格式比较单简。即然是发布报文那么主题和发布的内容是一定少了的。所以相对于别他报文来讲,发布报文对固定报头,可变报头,还有有效载荷都有需要。固定报头笔者就不用多讲了。把官方的列表拿过来大家自己看。就是那几个常用的信息。如下
看列表就是他的固定报头的二进制是00110000或是00110010或是00110100。分别对应QOS 0,QOS 1,QOS2。
可变报头里面存放了俩个信息对服务端来讲很重要。一个是主题,一个是消息ID。除了这俩个没有别的了。如下
官方的列表第一次看时候是有一点看不懂。特别是byte1,byte2是什么。如果看不懂他也没有事。你只要明白这些是组成元素就可以了。如上面列表的主题是“a/b”。有三个元素组成的。后面就是每一个元素对应的二进制。而LSB和MSB前面讲过了。
有效载荷就是存放就是发布的内容了。略过。
这一部分的代码笔者就不写了。因为笔者比较赖。只要上章读者们有去实现把相关订阅的主题保留住的话,那么发布报文的时候,只要从保留的主题中找到符合的。然后过通主题的信息找到对应的客户端连接。在发送信息就行了。但是一定要记得服务质量的要求。笔者这里只分析包的结构。如下
服务质量QOS 0的发布报文包
图片上笔者已经标出来相关的内容。分别为不同的颜色。我们知道服务质量QOS 0是没有回应的。所以只是单向的发送。比较简单。但是有一点要记得他好像没有消息ID。
服务质量QOS 1的发布报文包
我们可以看到跟QOS 0没有什么区别。主要是有了消息ID。但很重要。
服务质量QOS 1的发布报文确定(PUBACK)包
我们发现他没有有效载荷。除了固定报头之外,就是可变报头,同时只有一个消息ID。而且跟上面的发布报文的消息ID是相同的。
服务质量QOS 2的发布报文包
服务质量QOS 2的发布确定包(PUBREC)
相同的消息ID,没有有效载荷
服务质量QOS 2的发布确定包(PUBREL)
相同的消息ID,没有有效载荷
服务质量QOS 2的发布确定包(PUBCOMP)
相同的消息ID,没有有效载荷
MQTT——发布报文的更多相关文章
- MQTT——控制报文格式
解控制报文格式是学习MQTT中,笔者认为最为重要的一个知识点.MQTT的所有行为都离不开他.控制报文可以分为三个部分组成,分别为:固定报头.可以变报头.有效载荷部分. 注意:上面的说的报文的类型.是指 ...
- MQTT——连接报文
学习MQTT协议.如果只是看了相关文档就认为可以了.那是一个错误的观念.笔者为了能更好的去理解MQTT协议.看了不少相关的开源Broker的项目.可惜这些项目一般都是不完全的.不过从这些项目中笔者至少 ...
- MQTT——订阅报文
我们已经把相关的连接报文搞定了.笔者想来想去还是决定先讲解一下订阅报文(SUBSCRIBE ).如果传统的通信方式是客户端和服务端之间一般就直接传输信息.但是MQTT的通信方式是通过发布/订阅的方式进 ...
- MQTT - Connect报文解析
#include <bits/stdc++.h> using namespace std; int main() { ] = { /* * 固定报头: MQTT报文类型(1), 保留位 * ...
- javascript mqtt 发布订阅消息
js client使用paho-mqtt,官网地址:http://www.eclipse.org/paho/,参考http://www.eclipse.org/paho/clients/js/官网给出 ...
- MQTT——取消订阅报文和断开连接报文
笔者已经把连接报文,订阅报文,发布报文都讲解了完了.而接下来就是取消订阅报文和断开连接报文.和其他的报文比较的话,他们显示非常简单.甚至笔者觉得可以不必要拿出来讲.只要看一下MQTT文档就没有什么不清 ...
- 转战物联网·基础篇08-例说MQTT协议各控制报文
前面讨论了MQTT协议的控制报文的格式,下面分别举例探讨各个控制报文的详细内容. 01.CONNECT – 连接服务端 客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是CO ...
- 转战物联网·基础篇07-深入理解MQTT协议之控制报文(数据包)格式
在MQTT协议中,一个控制报文(数据包)的结构按照前后顺序分如下三部分: 结构名 中文名 解释说明 Fixed header 固定报头 报文的最开始部分,所有报文都包含这个部分 Variable ...
- MQTT 协议学习:006-订阅主题 与 对应报文(SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK)
背景 之前我们提到了怎么发布消息对应的报文:现在我们来看,订阅一个主题的报文是怎么样的. SUBSCRIBE - 订阅主题 客户端向服务端发送SUBSCRIBE报文用于创建一个或多个订阅.每个订阅注册 ...
随机推荐
- 混合高斯模型(Mixtures of Gaussians)和EM算法
这篇讨论使用期望最大化算法(Expectation-Maximization)来进行密度估计(density estimation). 与k-means一样,给定的训练样本是,我们将隐含类别标签用表示 ...
- Centos7搭建swarm集群
1. 准备 两台虚拟机,IP分别为: 192.168.1.104 192.168.1.105 保证能互相 ping 通 2. 修改虚拟机的 host,分别任 c1.c2 在 192.168.1.105 ...
- mvc的filter
如果想要记录ajax的请求和输出信息.内部发生异常记录日志.需要登录认证.需要权限判断:那mvc的各种filter可以帮助你实现你想要的.Mvc框架支持5种不同类型的过滤器:我会按照执行顺序进行简单的 ...
- 配置和启动Kubernetes服务
安装etcd服务 下载安装包 wget https://github.com/coreos/etcd/releases/download/v3.1.3/etcd-v3.1.3-linux-amd64. ...
- js循环生成多个easyui datagrid数据网格时,初始化表格
$.each( content, function(i, item){ var info_tpl = "";var result_tpl = "";var pr ...
- 聊聊Java中几种常用的设计模式
1.单例模式(有的书上说叫单态模式其实都一样) 该模式主要目的是使内存中保持1个对象.看下面的例子: package org.sp.singleton; //方法一 public class Sing ...
- ch3-form(get/post) $.ajax(get/post)
1 http(get)请求 提交的数据 用req.query接收 1.1 router.get() //http(get)请求方式 1.2 接收http(get)方式提交的数据 req.query 方 ...
- ZOJ2334 Monkey King 并查集 STL
题意:两家原始人(猴)打交道后成为一家猴,打交道时两家分别派出最帅的两位猴子,颜值各自减半,问每次打交道后新家族最帅的猴子的颜值.当然,已经是一家子就没有必要打交道了,因为没有猴希望颜值降低,毕竟还得 ...
- java web Servlet 学习笔记 -3 会话管理技术
Cookie和HttpSession 什么是会话: 用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 每个用户在使用浏览器与服务器进行会话的过 ...
- DevOps之服务-监控工具
唠叨话 关于德语噢屁事的知识点,仅提供精华汇总,具体知识点细节,参考教程网址,如需帮助,请留言. <DevOps教程> <DevOps之服务-监控工具> 注:关于监控工具的具体 ...