文章转载于https://www.cnblogs.com/hayasi/p/7792191.html

我们已经把相关的连接报文搞定了。笔者想来想去还是决定先讲解一下订阅报文(SUBSCRIBE )。如果传统的通信方式是客户端和服务端之间一般就直接传输信息。但是MQTT的通信方式是通过发布/订阅的方式进行的。笔者不知道他是否跟设计模式中的发布订阅模式有没有关系。可是他们思想却有一点相似之处。

客户端知道服务上有很多个主题。就好比如说有很多消息的分类一样子。有社会新闻、体育讲坛等。那么客户端只要找到自己感兴趣的进行订阅就可以了。一个客户端可以向服务器订阅多个主题。而所谓的发布就是客户端对不同的主题进行发布信息。即好比如新闻的发布者一样子。这个时候只要订阅这个主题的客户端就可以接收到来自服务端的新闻。我们的手机常常会接收到一些推送的信息。事实上有很多App应用都是用MQTT协议来进行的。所以不难看出服务端主要是负责客户端和客户端的之间信息的传输和信息管理。大至如图下

注意:发布者也是客户端。订阅者也是客户端

主题(Topic )

如果主题只是一个字符串值的话,那么显然会比较单调。这样子功能也显得比较无力。所以在主题上面就了所谓的分隔符和通配符的说法(个人想法)。分隔符的意思就是让主题可以分层次。就好如说主题“体育讲坛/篮球/NBA”。看到这样子的主题,请问一下你还有什么不明白的话。是不是感觉很有层次感。剩下只有一个问题?如果我们订阅了主题“体育讲坛/篮球/NBA”,并向主题“体育讲坛/篮球”发布一个信息。那么已经订阅主题“体育讲坛/篮球/NBA”的客户端们是不是可以接受到信息呢?反过来讲如果我们订阅了主题“体育讲坛/篮球”,向主题“体育讲坛/篮球/NBA”发信息,客户端们是否又能接受信息呢?

笔者就以HiveMQ作服务器来做一下上面的小实验。如下

客验结果显然是失败的——订阅主题“体育讲坛/篮球/NBA”的客户端根本收不到来自主题“体育讲坛/篮球“的发布信息。说明分隔符就是用于主题名的分层次。没有别的意思。

通过上面的实验我们知道如果想要收到NBA就是必须订阅主题“体育讲坛/篮球/NBA”。可是总是有一些人只要是篮球的新闻有喜欢。怎么办。通配符的功能就出来了。通配符有俩种——"+"和“#”。+为单层的通配符。表示当前这一层的全都合非。这样子以上面的说到的例子来做实验。我们订阅一个主题为“体育讲坛/篮球/+”。按照理解的意思就是只要是在“体育讲坛/篮球”的信息都是我们想要的。结果如下

我们可以看到笔者在“体育讲坛/篮球/NBA”和“体育讲坛/篮球/ABC”各发布了信息。结果他都能收到。那么如果我们对主题“体育讲坛/篮球”或是主题“体育讲坛/篮球/NBA/福州专场”发布信息呢?笔者试过了很可惜都不行。

记得我们上面说到有一些人只要跟篮球相关的都喜欢。可是如果使用通配符“+”是可以接近我们的要求。注意是接近。“+”通配符只是表示当前一层的。从当前的第二层就不行了。而本身的层也不算。就像上面的。只有篮球下的子一层才是合非的。讲到这里大家一定会想到用“#“通配符试试。没有错。“#“通配符就是表示当前本身和下面子层所有。如下

实验的结果很终满足了。

对于主题,在文档中有一个要求——主题不能以 ”#“ "+" "$" 为开头。对于”#“ ” +“的话,大家都好理解。那么”$“又是什么鬼。在文档我们可以看到这样子的字符"$SYS"。事实上他们是想说”$“开头的主题一般用于系统内部的一些主题。你们可以去找一些第三方的MQTT服务器。都会有很多以”$“开头的主题。

SUBSCRIBE报文

通过上面的介绍。笔者想你们一定对MQTT通信方式有了一定的概念。而本章的订阅报文就是用于告诉服务器我想要什么的主题了。通过前面几章的了解。我们知道报文的固定报头是少了的。笔者就以MQTT 3.1.1来介绍吧。如下

SUBSCRIBE报文的INT值是8。所以对应的二进制为1000。后面的DUP QOS RETAIN对应是0010。其中QOS是必须是01。对订阅者来讲,他一定希望自己的订阅是成功的。所以订阅报文的QOS是01就相当好理解了。如果不理解QOS是什么的话,请看一下前面几章。

订阅报文也有可变报头,可变报头只有一个消息ID。消息ID是从客端端开始分配的。笔者为什么样子认为呢?主要是看到客户端在发布信息的时候就要求消息ID。所以笔者才会觉得消息ID在客户端进行分配的。当然也不是什么报文都会消息ID的。但是有消息ID一般QOS大于0。

订阅报文的有效载荷里面存在了相关的订阅订题列表。前面说过可以支持一个客户端多个订阅。列表里面每有一主题项只有俩个值。一个表示主题名,一个表示服务质量要求(Requested QoS)。这里的服务质量要求(Requested QoS)和 固定报头的服务质量的值是一样子。但是用意却是不一样子。这里是指这个订阅者接收这主题的服务质量最大等级。举个列子吧。笔者订阅了一个主题主题“体育讲坛/篮球/NBA”,同时他的服务质量要求(Requested QoS)的值为1。这个时候有一个发布者在这个主题上发布一个服务质QOS为2。笔者还是可以收到这个发布者发来的信息。只是信息的服务质量QOS却变为1了。要明白QOS(1)和QOS(2)的执行行为是不样子的。这个后面章节会讲到。当然如果发布者在这个主题上发布一个服务质QOS为0。这就没有什么区别了。如下

对于有效载荷笔者这里就不多讲解了。也没有什么可说的。看文档的图片就够了如下。

宏观上:

微观上:

列表出我们可以看他订阅了俩个主题。一个主题”a/b“,一个主题”c/b“。上面列出大概的图片(宏观上)和比较细的图片(微观上)。如果看不懂也没有关系。笔者接下来会用代码来抓一包看看。相信在对照一下就明白列表出画的是什么。

现在让我们好好想想当服务器接收到来自客户端的订阅报文的时候要做些什么样子的反应呢?首先我们要明白如果服务端接收到一个订阅报文,第一步想到一定是查看订阅报文的格式是不是正确的。相关的主题名是不是为空的。主题名的写法是不是非法。这些一定离不开。当然对应的一些共有的验证笔者就不说了。一切没有问题的情况下,服务器会去看一下当前订阅者前面有没有订阅过相同的主题。如果有就替换当前的。如果没有就创建一下新的。然后服务器在根据当前主题查找一下符合保留的信息。如果有,就发送给当前的订阅者。然后发送一个订阅报文确定(SUBACK )。当然这前后没有规定。先发送一个订阅报文确定(SUBACK ),在处理保留的信息也是可以的。

注意:在发送符合保留的信息就要对QOS进行处理。上面笔者也讲过了。

SUBACK 报文

当服务端处理SUBSCRIBE报文的时候,都会生成一个SUBACK 报文来回应订阅者。笔者这里不想对他太过的讲解。他的内容也很简单。如下

对于SUBACK 报文的可变报头里面也只有一个消息ID。而且跟SUBSCRIBE报文的消息ID是一样子的。有效载何的内容存放是订阅主题的服务质量要求(Requested QoS)。笔者在MQTT 3.1 文档时面可以看到有多个主题的列子。可是在MQTT 3.1.1里面却没有。那么笔者就把MQTT 3.1.1的放在下里吧。读者们可以自行查看。

上面列表里面显示返回码,事实上是主题相关的服务质量要求(Requested QoS)。所以就可以知道他可以会返回四个值。如下

QOS 0:0x00 
QOS 1:0x01 
QOS2 :0x02
Failure :0x80

MQTT主题Topic讲解的更多相关文章

  1. Windows Azure Service Bus (5) 主题(Topic) 使用VS2013开发Service Bus Topic

    <Windows Azure Platform 系列文章目录> 项目文件,请在这里下载 在笔者之前的文章中Windows Azure Service Bus (1) 基础 介绍了Servi ...

  2. MQTT 单片机端讲解

    有空了和大家分享一下,如何从头架构一个高效mqtt并行客户端,基于传统GPRS等较差网络环境和网关等网络环境好的情景(当然仔细讲解mqtt的基本函数使很有必要的).---这会正忙着搬砖 MQTt协议 ...

  3. MQTT协议通俗讲解

    参考 Reference v3.1.1 英文原版 中文翻译版 其他资源 网站 MQTT官方主页 Eclipse Paho 项目主页 测试工具 MQTT Spy(基于JDK) Chrome插件 MQTT ...

  4. RabbitMQ入门(5)——主题(Topic)

    前面我们介绍了通过使用direct exchage,改善了fanout exchange只能进行虚拟广播的方式.尽管如此,直接交换也有自身的局限,它不能基于多个条件路由. 在我们的日志系统中,也许我们 ...

  5. (转)RabbitMQ学习之主题topic(java)

    http://blog.csdn.net/zhu_tianwei/article/details/40887775 参考:http://blog.csdn.NET/lmj623565791/artic ...

  6. ESA2GJK1DH1K基础篇: STM32+Wi-Fi(AT指令版)实现MQTT源码讲解

    前言 注: 本程序发送心跳包,发送温湿度,返回控制数据这三个发送是单独的,有可能凑到一起发. 由于本身程序就是复杂性的程序,所以这节程序没有使用中断发送,没有使用环形队列发送,为了避免多条消息可能凑到 ...

  7. ESA2GJK1DH1K基础篇: STM32+GPRS(AT指令版)实现MQTT源码讲解(支持Air202,SIM800)

    前言 注: 本程序发送心跳包,发送温湿度,返回控制数据这三个发送是单独的,有可能凑到一起发. 由于本身程序就是复杂性的程序,所以这节程序没有使用中断发送,没有使用环形队列发送,为了避免多条消息可能凑到 ...

  8. C# MQTT M2MQTT

    MQTT 入门介绍 MQTT是基于二进制消息的发布/订阅编程模式的消息协议 实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish).代理(Bro ...

  9. windows环境下apache-apollo服务器搭建及发布订阅测试

    查证了一些资料之后,发现 apache-apollo服务器使用的人还是挺多的,资料也比较齐全,所以直接选择 apache-apollo了,具体性能如何,先用起来再说吧: 1.下载 apache-apo ...

随机推荐

  1. DedeAMPZ配置php的curl扩展

    DedeAMPZ配置php的curl扩展  curl是一个利用URL语法在命令行方式下工作的文件传输工具.它支持很多协议:FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, ...

  2. 从FBV到CBV二(认证器)

    span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }.CodeMirror ...

  3. python中的定时任务

    使用threading模块中的Timer函数 from threading import Timer import time def execute_func(name, age, gender, h ...

  4. awk处理实记

    经grep日志后得到的数据格式如下: } . [debug][-- ::] SendDataStyled:{ , "innings" : "6189269620_0007 ...

  5. SQL SERVER 2012安装配置说明(多图详解)

    1. 优先安装软件 1. net framework3.5. 2. 在安装SQL SERVER 2012前需要3.5的支持.在WIN 2012系统可以在系统管理的添加角色和功能中安装,如下将[.NET ...

  6. Summer training round2 #5 (Training #21)

    A:正着DFS一次处理出每个节点有多少个优先级比他低的(包括自己)作为值v[i] 求A B 再反着DFS求优先级比自己高的求C #include <bits/stdc++.h> #incl ...

  7. java 文件上传与解析(excel,txt)

    excel上传与解析 https://blog.csdn.net/zsysu_it/article/details/79074067 txt解析 https://blog.csdn.net/CSDNw ...

  8. 封装ORM.py与mysql_client.py代码

    ORM.py ''' ORM: 对象关系映射 ---> 映射到数据库MySQL中的数据表 类名 ---> 表名 对象 ---> 一条记录 对象.属性 ---> 字段 模拟Dja ...

  9. c3p0连接池:com.mysql.cj.exceptions.InvalidConnectionAttributeException

    1 遇到的错误com.mysql.cj.exceptions.InvalidConnectionAttributeException: 四月 17, 2019 10:21:13 上午 com.mcha ...

  10. golang之 Array(数组)

    目录 一.Array(数组) 二.数组的定义 1. 基本语法 三.数组的初始化 1. 方式一 2. 方式二 3. 方式三 四.数组的遍历 1. 方式一:for循环遍历 2. 方式二:for range ...