MQTT协议详解一

2023-11-19

首先给出MQTT协议的查看地址:http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html

当然也有PDF版的,百度一下,不过个人感觉还是官网上的字体和排版最舒服。

那么这个协议是做什么的或有什么特色呢?下面是mqtt.org上的介绍:

It was designed as an extremely lightweight publish/subscribe messaging transport. It is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium. For example, it has been used in sensors communicating to a broker via satellite link, over occasional dial-up connections with healthcare providers, and in a range of home automation and small device scenarios. It is also ideal for mobile applications because of its small size, low power usage, minimised data packets, and efficient distribution of information to one or many receivers

MQTT轻量级基于代理的发布/订阅的消息传输协议,它可以通过很少的代码和带宽和远程设备连接,例如可以通过卫星和代理连接,通过拨号和医疗保健提供者连接,以及在一些自动化或小型设备上连接,而且由于小巧,省电,协议开销小和能高效的向一和多个接收者传递信息,故非常适用于移动设备上。

相信在想深入学习这协议必是奔着解决某个问题而来的,上面给出了适用的场景,

我之所以想深入的学习和了解这个协议,理由如下:

1、可以实现手机消息推送(PUSH)

2、协议简单,最小的头部只需2个字节,特别适合于嵌入式中。

3、这是个了解什么是协议绝好的例子。相比于其它复杂的协议例如tcp,http协议,至少说明文档看的下去。

在这里,我以推送为例子说明,虽然现在现成的推送解决方案已经比较成熟,但是这个Repeat ReInvent the Whell还是要做一下,什么都是拿来主义,和搬运工有什么区别。

一、需要的环境:

1、PHP+Apache或Nginx

2、安装开源代理程序Mosquitto,这里用其做为代理服务器,负责连接和分发。

安装方法很简单,http://mosquitto.org/files/   binary是编译好的,source是源码安装需要的(make & make install 就行)

唯 一要配置的就是在解压后的config.mk,安装完后设置文件是mosquitto.conf

当然主要是设置是否支持ssl,还有就是config.mk最下面的安装位置的设定。这里一切默认。

默认启动是绑定的IP是本地IP,端口是1883可以在mosquitto.conf里设置(要去掉前面的#字注释),linux 中 -c 可以指定设置文件并运行

比 如: mosquitto -c /etc/mosquitto.conf

二、协议初解

先说一下整个协议的构造,整体上协议可拆分为:

                    固定头部+可变头部+消息体

协议说白了就是对于双方通信的一个约定,比如传过来一段字符流,第1个字节表示什么,第2个字节表示什么。。。。一个约定。

所以在固定头部的构造如下:


1、MessageType(0和15保留,共占4个字节)

public $operations=array(
         "MQTT_CONNECT"=>1,//请求连接
         "MQTT_CONNACK"=>2,//请求应答
         "MQTT_PUBLISH"=>3,//发布消息
         "MQTT_PUBACK"=>4,//发布应答
         "MQTT_PUBREC"=>5,//发布已接收,保证传递1
         "MQTT_PUBREL"=>6,//发布释放,保证传递2
         "MQTT_PUBCOMP"=>7,//发布完成,保证传递3
         "MQTT_SUBSCRIBE"=>8,//订阅请求
         "MQTT_SUBACK"=>9,//订阅应答
         "MQTT_UNSUBSCRIBE"=>10,//取消订阅
         "MQTT_UNSUBACK"=>11,//取消订阅应答
         "MQTT_PINGREQ"=>12,//ping请求
         "MQTT_PINGRESP"=>13,//ping响应
         "MQTT_DISCONNECT"=>14//断开连接
        ); 
2、DUP flag

 其是用来在保证消息传输可靠的,如果设置为1,则在下面的变长头部里多加MessageId,并需要回复确认,保证消息传输完成,但不能用于检测消息重复发送。

3、Qos

主要用于PUBLISH(发布态)消息的,保证消息传递的次数。

00表示最多一次 即<=1

01表示至少一次  即>=1

10表示一次,即==1

11保留后用

4、Retain

 主要用于PUBLISH(发布态)的消息,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它。如果不设那么推送至当前订阅的就释放了。

5、固定头部的byte 2

是用来保存接下去的变长头部+消息体的总大小的。

但是不是并不是直接保存的,同样也是可以扩展的,其机制是,前7位用于保存长度,后一部用做标识。

我举个例了,即如果计算出后面的大小为0<length<=127的,正常保存

如果是127<length<16383的,则需要二个字节保存了,将第一个字节的最大的一位置1,表示未完。然后第二个字节继续存。

拿130来说,第一个字节存10000011,第二个字节存000000001,也就是0x83,0x01,把两个字节连起来看,第二个字节权重从2的8次开始。

同起可以加第3个字节,最多可以加至第4个字节。故MQTT协议最多可以实现268 435 455 (0xFF, 0xFF, 0xFF, 0x7F)将近256M的数据。可谓能伸能缩。

 可变头部


这个是可变头部的全貌。

1、首先最上面的8个字节是Protocol Name(编码名),UTF编码的字符“MQIsdp”,头两个是编码名提长为6。

这里多说一些,接下去的协议多采用这种方式组合,即头两个字节表示下一部分的长,然后后面跟上内容。这里头两个字节长为6,下面跟6个字符“MQIsdp”。

2、Protocol Version,协议版本号,v3 也是固定的。

3、Connect Flag,连接标识,有点像固定头部的。8位分别代表不同的标志。第1个字节保留。

Clean Session,Will flag,Will Qos, Will Retain都是相对于CONNECT消息来说的。

Clean Session:0表示如果订阅的客户机断线了,那么要保存其要推送的消息,如果其重新连接时,则将这些消息推送。

                            1表示消除,表示客户机是第一次连接,消息所以以前的连接信息。

Will Flag表示如果客户机在不是在发送DISCONNECT消息中断,比如IO错误等,将些置为1,要求重传。并且下且的WillQos和WillRetain也要设置,消息体中的Topic和MessageID也要设置,就是表示发生了错误,要重传。

Will Qos,在CONNECT非正常情况下设置,一般如果标识了WillFlag,那么这个位置也要标识。

Will RETAIN:同样在CONNECT中,如果标识了WillFlag,那么些位也一定要标识

usename flag和passwordflag,用来标识是否在消息体中传递用户和密码,只有标识了,消息体中的用户名和密码才用效,只标记密码而不标记用户名是不合法的。

4、Keep Alive,表示响应时间,如果这个时间内,连接或发送操作未完成,则断开tcp连接,表示离线。

5、Connect Return Code即通常于CONNACK消息中,表示返回的连接情况,我可以通过此检验连接情况。


6、Topic Name,订阅消息标识,MQTT是基于订阅/发布的消息,那么这个就是消息订阅的标识,像新闻客户端里的订阅不同的栏目一样。用于区别消息的推送类别。

主要用于PUBLISH和SUBSCRIBE中。最大可支持32767个字符,即4个字节。

消息体(PayLoad)

只有3种消息有消息体CONNECT,SUBSCRIBE,SUBACK

CONNECT主要是客户机的ClientID,订阅的Topic和Message以及用户名和密码,其于变长头部中的will是对应的。

SUBSCRIBE是包含了一系列的要订阅的主题以及QOS。

SUBACK是用服务器对于SUBSCRIBE所申请的主题及QOS进行确认和回复。

PUBLISH是消息体中则保存推送的消息,以二进制形式,当然这里的编辑可自定义。

7、Message Identifier

包含于PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK.

其为16位字符表示,用于在Qos为1或2时标识Message的,保证Message传输的可靠性。

至于具体的消息例子,我们在后面的代码中慢慢体现。





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MQTT协议详解一 的相关文章

  • 处理照片上传的最佳方式是什么?

    我正在为一个家庭成员的婚礼制作一个网站 他们要求的一个功能是一个照片部分 所有客人都可以在婚礼结束后前往并上传他们的照片 我说这是一个很棒的想法 然后我就去实现它 那么只有一个问题 物流 上传速度很慢 现代相机拍摄的照片很大 2 5 兆 我
  • MySQL 查询按父级排序然后子级排序

    我的数据库中有一个页面表 每个页面可以有一个父页面 如下所示 id parent id title 1 0 Home 2 0 Sitemap 3 0 Products 4 3 Product 1 5 3 Product 2 6 4 Prod
  • C++ 中是否有与 PHP 的explode() 函数等效的函数? [复制]

    这个问题在这里已经有答案了 可能的重复 在 C 中分割字符串 https stackoverflow com questions 236129 splitting a string in c 在 PHP 中 explode 函数将获取一个字
  • cUrl 在本地主机上工作正常,但在服务器上不起作用,仅显示空白页面

    当我在服务器上运行以下代码时 它只显示空白页面并突然停止进一步执行 我还检查了已安装的服务器上的 cUrl 这是我的代码 ftp server ftps server Voorraadtonen link csv ch curl init
  • 通过 AJAX 加载的页面上的 reCAPTCHA 字段不会加载。建议?

    实例 没有 AJAX http utsarotaract org inc email php 使用 AJAX 单击给我们发送电子邮件链接 http utsarotaract org contact php 当我查看源页面时 一切正常 但是当
  • cookie神秘重现的原因是什么?

    我正在开发一个使用 cookie 来存储会话信息的 Web 应用程序 我已经手动删除了会话 cookie 因为我正在处理代码的另一部分 我不需要登录会话 然而 在页面重新加载几次后 会话 cookie 神秘地重新出现 其中包括我之前出于测试
  • PDO 从表中获取一列到一维数组中

    我对 PDO 和让它们与 MySQL 一起工作还很陌生 我似乎在插入新数据和检索单个结果方面进展顺利 但是我坚持了下来 我有一张由配料组成的桌子 我试图将所有配料放入一个数组中 我已经直接在 SQL 中运行查询 它显示了所有结果 但是使用
  • Laravel Eloquent 更新(如果已进行更改)

    如果记录发生更改 是否有任何方法可以使用 eloquent 模型更新 Laravel 中的记录 我不希望任何用户无缘无故地一遍又一遍地请求数据库 只需点击按钮即可保存更改 我有一个javascript根据页面中是否发生更改来启用和禁用保存按
  • 颠倒句子中的“英语”单词

    我有一个字符串 其中可能使用多种语言 例如 and this is in English this is going to be continued 我只想反转英语单词 所以结果应该是这样的 English in is this and c
  • PHP Web 应用程序中的 Ace 编辑器

    我正在制作一个小型网络应用程序 允许用户通过以下方式提交 html css 和 javascript 内容王牌编辑器 http ace ajax org 在此编辑器中 将存储的内容回显到编辑器中就足够了 但是无论如何我找不到将用户输入提交到
  • PHP Microsoft Excel 文件生成/导出类

    我一直在寻找一个好的 Excel 文件生成类 但还没有找到 我的首要问题是 虽然我可以在 Excel 中打开导出的文件 运行 2007 年 但我总是收到一条警告 文件的格式与文件扩展名不同 我注意到 phpMyAdmin 中的 Excel
  • 如何在 PHP >= 5.4 的特征中重载类构造函数

    在 PHP 5 中 我可以重载构造函数 以及任何其他方法 但是如果我得到这样的代码 class Base public function construct a b echo a b public function sayHello ech
  • 为什么使用 mysql_real_escape_string,addslashes 不会阻止一切?

    我正在查看文档并偶然发现了 mysql real escape string 我不明白为什么当您可以只使用addslashes 时它很有用 有人可以向我展示一个场景来说明它为什么有用吗 我也很好奇为什么它需要数据库连接 这似乎是一个很大的开
  • 通过 HTML 将复杂变量传递给 javascript 的正确方法

    我试图摆脱使用 PHP 的 htmlentities 但我在这里停止了 但后来我想 我不做替换和检查特殊字符 而是只 JSON 整个对象 这提供了一个非常不受欢迎的结果 其中包含大量双引号 那么我应该怎么做呢 我应该为每个图像分配一个数字唯
  • 在 PHP 中设置 X-Frame-Options

    如何在我的 PHP 代码中设置 X Frame Options 以便它出现在我的服务器的所有网页中 基本上 我试图避免 iframe 加载我的网络应用程序 在您的 php 文件中使用以下内容 该文件将响应输出到客户端 header X Fr
  • 如何在 Zend 中使用 cookie?

    如何使用 Zend Http Cookie 来设置和读取 cookie 我尝试像这样设置cookie cookie new Zend Http Cookie TestCookie TestValue localhost com 但没有生成c
  • 通过 PHP 脚本重新启动 Nginx

    我目前正在努力使我的 WordPress 插件与 nginx 兼容 该插件需要访问 conf文件在wp content uploads目录 以便它可以添加所需的规则 目前 它更新了 htaccess文件位于同一目录中 更改立即生效 无需干预
  • 正则表达式 - 从字符串末尾搜索

    我如何从字符串末尾定位某些内容 complexthing 50 other 50 MORE 50 我想以 50 结尾 但是这个 复杂的东西 可以以 结尾 所以在这种情况下 我不能在 处打断 因为乞求可能会让它感到困惑 所以对我来说最简单的正
  • 在 Codeigniter 中显示来自连接的数据

    我正在使用简单的联接从两个数据库中提取数据 这是模型中的连接 function com control this gt db gt select this gt db gt from comments this gt db gt join
  • Paypal Rest API - 来自批准 URL 的令牌生命周期

    我使用 Paypal Rest API 我的问题是 有多长token来自批准 URL 有效吗 我想将此令牌 也包含我的令牌 存储到数据库并生成带有我的令牌的链接 稍后 如果我单击此链接 将我的令牌替换为 paypal 令牌 我想重定向到 p

随机推荐

  • Android webview加载网页

    webview尝试 一 在线加载网页 例百度 webview布局很简单xml如下
  • 快速椭圆检测代码调试记录

    代码环境 Windows11 vs2019 opencv3 3 1 Debugx64 一 代码注释 1 realpath PATH MAX basename 这几句是为了在Ubuntu中运行时 寻找路径用的 Ubuntu需要比较严格的路径
  • 人工智能AI工具汇总(AIGC ChatGPT时代个体崛起)

    Name Category Website Description 描述 AIGC时代 超级个体的崛起 小报童 https xiaobot net p SuperIndividual 介绍AIGC ChatGPT 使用技巧与搞钱方式 Mas
  • React学习(编程式导航)

    学习目标 提示 这里可以添加学习目标 1 编程式导航 编程式导航 提供了通过脚本代码实现页面跳转的功能 主要api函数包含在路由对象参数 history中 this props history push login 跳转到登录路径 保留访问
  • java 调用controller_java调用controller方法

    我们有一个路由StudentController 里面有一个方法count 如果要在另外一个GradeController中调用count 方法有2种方式 因为StudentController是一个class 不是接口 接口一般都是 Au
  • 用 plt 画折线图(将训练过程中的每个epoch 的准确率和损失用图的形式展示出来)

    代码 import matplotlib pyplot as plt epochs range 0 4 acc 2 1 2 3 1 4 5 loss 1 1 1 4 0 8 0 6 plt plot epochs acc color r l
  • python sklearn 梯度下降法_【机器学习】梯度下降法(Gradient descent)

    说明 以下内容为学习刘建平老师的博客所做的笔记 梯度下降 Gradient Descent 小结 www cnblogs com 因为个人比较喜欢知乎文章的编辑方式 就在这里边记笔记边学习 喜欢这个博客的朋友 可以去刘建平老师的博客foll
  • 使用google的免费GPU

    1 打开网页 输入Google colab 2 点击 修改 gt 笔记本设置 3 点击使用GPU 常用命令 print torch version print torch cuda is available
  • 1.centos7安装docker

    本文目录 1 docker 安装 1 安装步骤 2 安装是否成功校验 3 docker加速配置 4 hello world来袭 验证安装是否ok 2 卸载docker 3 卸载较旧版本docker 使用docker必备的三个官方网站 doc
  • 无线路由、AP、网桥之区别详解篇

    通过无线上网冲浪 现在已经不是新鲜的事情 随着近一两年无线 网络的飞速发展 从企业到家庭都开始在不同的领域体验着 自由上网 的乐趣 笔者接触无线网络也有一段时间了 经常在一些无线论坛逛游 无论是在现实生活还是在论坛中 总会有朋友不断的问这样
  • HyperLedger Fabric 实践错误收集

    HyperLedger Fabric 实践错误收集 在ubuntu中通过docker compose启动容器的时候报错 ERROR for cli Cannot create container for service cli Confli
  • 光模块之SR、LRM、LR、ER 、ZR对比介绍

    SFP介绍 现有的ARUBA 原来的HP 万兆模块有多种 除了MMF表示多模SMF表示单模 SR LRM LR ER等都代表什么意思 本文做个简单对比介绍 将帮助您根据您的实际需要选择合适的10G SFP 模块 Aruba 10G SFP
  • 英语软件的日志怎么写

    今天一个外企个小伙伴跑来跟我说 老板说他的程序里的英语写的太烂 让我教他怎么写日志 虽然我自己用英语写log 也还马马虎虎 但是让我系统的介绍 我也犯了难 好在 我做过自然语言处理 NLP 也做过针对计算机系统的日志的挖掘 所以我知道有个东
  • Lua脚本在redis中的使用学习

    Lua脚本在redis中的使用学习 0 前言 不同于之前遇到的redisTemplate的简单set get方法 这里是使用Redis脚本执行redis操作 DefaultRedisScript
  • Linux宝塔面板 网址忘记了,或者账号密码错误怎么办?

    在linux中安装宝塔面板后会生成网址 账号和密码 如果网址忘记了那将进不去宝塔面板 bt 命令 输入bt后 在输入14就可以查看宝塔面板详细信息 root localhost bt 宝塔面板命令行 1 重启面板服务 8 改面板端口 2 停
  • struts2-输入校验、xml校验的使用

    1 输入校验 直接在Action类里添加相应的方法 这里定义了一个中间变量 前面我直接返回SUCCESS ERROR会报错 具体我还要研究一下 struts xml login jsp 2 xml校验 在XXAction的同级目录下 建立X
  • Qt Desginer布局方法

    关于Qt Desginer中的布局方法 网上教程少之又少 个人经过反复的实践和摸索 觉得可以用一句话来概括 先不断地进行小布局 然后对整体进行大布局 先不断地进行小布局的目的就是将同为一组的控件按某个格式排列使界面干净有序 同时方便以后对整
  • [教程]Hexo + Github 搭建自己的专属博客

    教程 Hexo Github 搭建自己的专属博客 文章目录 教程 Hexo Github 搭建自己的专属博客 1 安装Git和NodeJS 2 安装Hexo 3 加载主题 4 修改主题配置 5 将博客部署在GitHub上 6 写文章并上传
  • 在Mac上安装MongoDB

    1 访问MongoDB官方下载地址 http www mongodb org downloads 2 解压文件mongodb osx ssl x86 64 4 0 9 tgz 解压之后会变成mongodb osx x86 64 4 0 9文
  • MQTT协议详解一

    首先给出MQTT协议的查看地址 http public dhe ibm com software dw webservices ws mqtt mqtt v3r1 html 当然也有PDF版的 百度一下 不过个人感觉还是官网上的字体和排版最