热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mqttsession保持订阅消息_常用物联网协议MQTT详解

常用物联网协议-----MQTT详解协议简述MQTT协议实现方式实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份&#

常用物联网协议-----MQTT详解

协议简述

MQTT协议实现方式

实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分:        (1)Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload);

        (2)payload,可以理解为消息的内容,是指订阅者具体要使用的内容。

发布/订阅模型允许MQTT客户端以一对一、一对多和多对一方式进行通讯。

下图是MQTT的发布/订阅消息模式

a339fda2f3e82a7958ee9f4d21fe77b0.png

网络传输与应用消息

MQTT会构建底层网络传输:它将建立客户端到服务器的连接,提供两者之间的一个有序的、无损的、基于字节流的双向传输。当应用数据通过MQTT网络发送时,MQTT会把与之相关的服务质量(QoS)和主题名(Topic)相关联。

下图是MQTT为可靠传递消息的三种消息发布服务质量

d933a2c566f3f44f4809e1390119b243.png

MQTT客户端

一个使用MQTT协议的应用程序或者设备,它总是建立到服务器的网络连接。客户端可以:

(1)发布其他客户端可能会订阅的信息;

(2)订阅其它客户端发布的消息;

(3)退订或删除应用程序的消息;

(4)断开与服务器连接。

MQTT服务器

MQTT服务器以称为“消息代理”(Broker),可以是一个应用程序或一台设备。它是位于消息发布者和订阅者之间,它可以:

(1)接受来自客户的网络连接;

(2)接受客户发布的应用信息;

(3)处理来自客户端的订阅和退订请求;

(4)向订阅的客户转发应用程序消息。

MQTT协议中的订阅、主题、会话

订阅(Subscription)

订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器。

会话(Session)

每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接。

主题名(Topic Name)

连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。

主题筛选器(Topic Filter)

一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。

负载(Payload)

消息订阅者所具体接收的内容。

MQTT协议中的方法

MQTT协议中定义了一些方法(也被称为动作),来于表示对确定资源所进行操作。这个资源可以代表预先存在的数据或动态生成数据,这取决于服务器的实现。通常来说,资源指服务器上的文件或输出。主要方法有:

(1)Connect。等待与服务器建立连接。

(2)Disconnect。等待MQTT客户端完成所做的工作,并与服务器断开TCP/IP会话。

(3)Subscribe。等待完成订阅。

(4)UnSubscribe。等待服务器取消客户端的一个或多个topics订阅。

(5)Publish。MQTT客户端发送消息请求,发送完成后返回应用程序线程。

MQTT协议数据包结构

在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、 可变头(Variable header)、 消息体(payload)三部分构成。MQTT的传输格式非常精小,最小的数据包只有2个bit,且无应用消息头。

(1)固定头(Fixed header)。存在于所有MQTT数据包中,表示数据包类型及数据包的分组类标识。

(2)可变头(Variable header)。存在于部分MQTT数据包中,数据包类型决定了可变头是否存在及其具体内容。

(3)消息体(Payload)。存在于部分MQTT数据包中,表示客户端收到的具体内容。

如何通过MQTT传输设备数据 

下面以我们的网关为例,介绍将如何通过MQTT传输我们的数据。

每一个网关属于MQTT传输中的一个client,客户端通过网络连接到服务端,它可以

  • 发布应用消息给其它相关的客户端。

  • 订阅以请求接受相关的应用消息。

  • 取消订阅以移除接受应用消息的请求。

  • 从服务端断开连接。

CONNECT – 连接服务端

客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是CONNECT报文,在一个网络连接上,客户端只能发送一次CONNECT报文。服务端必须将客户端发送的第二个CONNECT报文当作协议违规处理并断开客户端的连接。有效载荷包含一个或多个编码的字段。包括客户端的唯一标识符,Will主题,Will消息,用户名和密码。除了客户端标识之外,其它的字段都是可选的,基于标志位来决定可变报头中是否需要包含这些字段。CONNECT报文如下表所示:

492b00eea7f7706b8b690feb2d5b2dac.png

1. 网络连接建立后,如果服务端在合理的时间内没有收到CONNECT报文,服务端应该关闭这个连接。2. 服务端必须验证CONNECT报文,如果报文不符合规范,服务端不发送CONNACK报文直接关闭网络连接。3. 服务端可以检查CONNECT报文的内容是不是满足任何进一步的限制,可以执行身份验证和授权检查。如果任何一项检查没通过,它应该发送一个适当的、返回码非零的CONNACK响应,并且必须关闭这个网络连接。如果验证成功,服务端会执行下列步骤。
  • 如果ClientId表明客户端已经连接到这个服务端,那么服务端必须断开原有的客户端连接

  • 服务端必须执行清理会话的过程。

  • 服务端必须发送返回码为零的CONNACK报文作为CONNECT报文的确认响应

  • 开始消息分发和保持连接状态监视。

允许客户端在发送CONNECT报文之后立即发送其它的控制报文;客户端不需要等待服务端的CONNACK报文。如果服务端拒绝了CONNECT,它不能处理客户端在CONNECT报文之后发送的任何数据。

PUBLISH – 发布消息

PUBLISH控制报文是指从客户端向服务端或者服务端向客户端传输一个应用消息。PUBLISH报文如下:

5e02f57539090b69d9591db2a1729bfa.png

f4f2f4b78820777f61c422be87669acf.png

有效载荷(包含发布的应用消息)...

客户端使用PUBLISH报文发送应用消息给服务端,目的是分发到其它订阅匹配的客户端。服务端使用PUBLISH报文发送应用消息给每一个订阅匹配的客户端。

客户端使用带通配符的主题过滤器请求订阅时,客户端的订阅可能会重复,因此发布的消息可能会匹配多个过滤器。对于这种情况,服务端必须将消息分发给所有订阅匹配的QoS等级最高的客户端。服务端之后可以按照订阅的QoS等级,分发消息的副本给每一个匹配的订阅者。

收到一个PUBLISH报文时,接收者的动作取决于QoS等级。如果服务端实现不授权某个客户端发布PUBLISH报文,它没有办法通知那个客户端。它必须按照正常的QoS规则发送一个正面的确认,或者关闭网络连接。

SUBSCRIBE - 订阅主题

客户端向服务端发送SUBSCRIBE报文用于创建一个或多个订阅。每个订阅注册客户端关心的一个或多个主题。为了将应用消息转发给与那些订阅匹配的主题,服务端发送PUBLISH报文给客户端。SUBSCRIBE报文也(为每个订阅)指定了最大的QoS等级,服务端根据这个发送应用消息给客户端。消息报文如下所示:

ff2fdef5cecf89f5d2f00e0acaad67b3.png

f2a9ece57e0d85d71f08a27b9e201ded.png

0363468915cf6bb6ce85aed77918b135.png

服务端收到客户端发送的一个SUBSCRIBE报文时,必须使用SUBACK报文响应。SUBACK报文必须和等待确认的SUBSCRIBE报文有相同的报文标识符。允许服务端在发送SUBACK报文之前就开始发送与订阅匹配的PUBLISH报文。如果服务端收到一个SUBSCRIBE报文,报文的主题过滤器与一个现存订阅的主题过滤器相同,那么必须使用新的订阅彻底替换现存的订阅。新订阅的主题过滤器和之前订阅的相同,但是它的最大QoS值可以不同。与这个主题过滤器匹配的任何现存的保留消息必须被重发,但是发布流程不能中断。如果主题过滤器不同于任何现存订阅的过滤器,服务端会创建一个新的订阅并发送所有匹配的保留消息。如果服务端收到包含多个主题过滤器的SUBSCRIBE报文,它必须如同收到了一系列的多个SUBSCRIBE报文一样处理那个,除了需要将它们的响应合并到一个单独的SUBACK报文发送

DISCONNECT –断开连接

DISCONNECT报文是客户端发给服务端的最后一个控制报文。表示客户端正常断开连接。DISCONNECT报文格式如下:

880649babebb5285e6b67bec0f022ff3.png

服务端必须验证所有的保留位都被设置为0,如果它们不为0必须断开连接。DISCONNECT报文没有可变报头,没有有效载荷。客户端发送DISCONNECT报文之后,必须关闭网络连接,不能通过那个网络连接再发送任何控制报文。服务端在收到DISCONNECT报文时,必须丢弃任何与当前连接关联的未发布的遗嘱消息,关闭网络连接。

MQTT数据包格式

设备通过CONNECT连接到服务端以后,设备可以发布消息到服务端,消息体类容具体格式如下图所示:

fec3d47fc525f999a61ec2b84337eb8b.png

fdfe86ac0b16c5510b2341a2a9cbcfbd.png

通讯包通过MQTT携带JSON数据的方式进行传输。

JSON数据文本采用“UTF-8” 的编码方式。

JSON数据文本压缩采用Zlib库压缩。

简单模型的定义

设备基本信息JSON描述:

177fc8ee7e37f552e461a9f4d97da275.png

设备属性信息JSON描述:

51ad92cd9e2fe3e78b4e191e195b9034.png

设备报警信息JSON描述:

32c5e848519d137cc749dd30c7aa723b.png

其中Json数据包中“实际数据”指具体设备采集值,如能耗监控系统中,BMS数据格式如下所示:

42a4b18f536957a92a704374b05894c5.png

复杂模型的定义:

193fe18899c79bafb2bef69a3ef9a9a2.png




推荐阅读
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 如何在php文件中添加图片?
    本文详细解答了如何在php文件中添加图片的问题,包括插入图片的代码、使用PHPword在载入模板中插入图片的方法,以及使用gd库生成不同类型的图像文件的示例。同时还介绍了如何生成一个正方形文件的步骤。希望对大家有所帮助。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • 本文介绍了一种在PHP中对二维数组根据某个字段进行排序的方法,以年龄字段为例,按照倒序的方式进行排序,并给出了具体的代码实现。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
author-avatar
Openset
Less is more!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有