安装

下载安装包

wget https://www.emqx.com/zh/downloads/broker/5.0.8/emqx-5.0.8-macos11-amd64.tar.gz

很遗憾,下载过程中报错,报错信息如下:

AndydeMacBook-Pro:mqtt andy$ wget https://www.emqx.com/zh/downloads/broker/5.0.8/emqx-5.0.8-macos11-amd64.tar.gz
dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylibReferenced from: /usr/local/bin/wgetReason: image not found
Abort trap: 6

执行以下命令,安装包版本

# 第一步
brew install rbenv/tap/openssl@1.0# 第二步
ln -sfn /usr/local/Cellar/openssl@1.0/1.0.2t /usr/local/opt/openssl

重新执行下载命令

安装

mkdir -p emqx && tar -zxvf emqx-5.0.8-macos11-amd64.tar.gz -C emqx

启动 EMQX

./emqx/bin/emqx start

并没有启动成功,报错信息如下

AndydeMacBook-Pro:mqtt andy$ ./emqx/bin/emqx start
./emqx/bin/emqx: line 10: realpath: command not found
dyld: lazy symbol binding failed: Symbol not found: ____chkstk_darwinReferenced from: /Users/andy/tool/util/mqtt/emqx/erts-12.2.1/bin/beam.smp (which was built for Mac OS X 11.0)Expected in: /usr/lib/libSystem.B.dylibdyld: Symbol not found: ____chkstk_darwinReferenced from: /Users/andy/tool/util/mqtt/emqx/erts-12.2.1/bin/beam.smp (which was built for Mac OS X 11.0)Expected in: /usr/lib/libSystem.B.dylib
Please ensure it is running on the correct platform:
arch: "x86_64-apple-darwin20.6.0"
wordsize: 64
os: "macos11"
erlang: "24.2.1-1"
elixir: "none"
relform: "tgz"
Version=5.0.8

完了,芭比Q了,安装包在mac os11平台才能运行,我电脑的版本是macos 10,官方也并没有提供macos 10的编译包,看来只能看docker启动了。

Docker 安装

拉取镜像

docker pull emqx/emqx:5.0.8

启动容器

docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.0.8

DashBoard

在浏览器打开 localhost:18083,默认账号密码为: admin/public, 第一次登录需要修改默认密码,然后重新登录。

从上面的截图中可以看出连接数、主题数、订阅数以及服务器运行的相关信息。默认界面显示英文,可以通过设置里面修改成中文,看起来舒服一点,哈哈。

客户端验证

Websocket

打开 Dashboard,进入 问题分析 -> WebSocket 客户端 页面中可以在浏览器中使用 MQTT over WebSokcet 客户端快速接入 EMQX。

从上图看出自己发布主题为hello的消息,被自己订阅消费。

MQTTX

MQTTX 是一款优雅的跨平台 MQTT 5.0 开源桌面客户端工具,支持在 macOS、Linux 和 Windows 上运行。

工具下载地址: https://mqttx.app/zh

操作步骤: 创建客户端 -> 订阅消息

上图显示从DashBoard WS客户端发送的消息,在MQTTX工具中订阅成功。至此MQTT验证流程ok。

MQTT协议特性

保留消息

MQTT 客户端向服务器发布消息时,可以设置保留消息标志。一个主题下最新一条保留消息会驻留在消息服务器,后来的订阅者订阅主题时仍可以接收该消息。

保留消息主要解决MQTT客户端之间发送消息、消费消息时间差的问题。假设没有保留消息的话,会出现以下情况:

  1. 在T1时间,设备A发送消息 A
  2. 在T2时间点,消息订阅者 设备B尚未启动
  3. T2时间点在T1时间点之后,则设备B收不到消息A

保留消息完美的解决了上述问题,如下图,设备001向 Retain_Topic 主题发送主题消息(此时设备B尚不在线)

新增设备B,并订阅 Retain_Topic 主题,可以看到保留消息已经被消费。

应用场景

发布订阅模式虽然能让消息的发布者与订阅者充分解耦,但也存在一个缺点,即订阅者无法主动向发布者请求消息。订阅者何时收到消息完全依赖于发布者何时发布消息,这在某些场景中就产生了不便。借助保留消息,新的订阅者能够立即获取最近的状态,而不需要等待无法预期的时间,例如:

  • 智能家居设备的状态只有在变更时才会上报,但是控制端需要在上线后就能获取到设备的状态;
  • 传感器上报数据的间隔太长,但是订阅者需要在订阅后立即获取到最新的数据;
  • 传感器的版本号、序列号等不会经常变更的属性,可在上线后发布一条保留消息告知后续的所有订阅者。

保留消息存储

服务器会为每个主题保留最新的一条保留消息,保留消息的保存时间与服务器的设置有关。若服务器设置保留消息存储在内存,则 MQTT 服务器重启后消息即会丢失;若存储在磁盘,则服务器重启后保留消息仍然存在。如下图

删除保留消息

保留消息跟会话无关,即使会话关闭,保留消息也不会删除。删除保留消息方式有如下几种:

  • 客户端往某个主题发送一个 Payload 为空的保留消息,服务端就会删除这个主题下的保留消息;
  • 在 MQTT 服务器上删除,比如 EMQX MQTT 服务器提供了在 Dashboard 上删除保留消息的功能;

  • MQTT 5.0 新增了消息过期间隔属性,发布时可使用该属性设置消息的过期时间,不管消息是否为保留消息,都将会在过期时间后自动被删除。

遗嘱消息

遗嘱消息是 MQTT 为那些可能出现 意外断线 的设备提供的将 遗嘱 优雅地发送给第三方的能力。意外断线包括但不限于:

  • 因网络故障或网络波动,设备在保持连接周期内未能通讯,连接被服务端关闭
  • 设备意外掉电
  • 设备尝试进行不被允许的操作而被服务端关闭连接,例如订阅自身权限以外的主题等

MQTT 客户端向服务器发起连接请求时,可以设置是否发送遗嘱消息(Will Message)标志,和遗嘱消息主题(Topic)与内容(Payload)。通俗点的理解,即设备生前(建立连接时)立下遗嘱,然后在意外死后让订阅者获取到此类信息,即遗嘱消息。

遗嘱消息与保留消息的共同点都是在特殊的情况下让订阅方感知设备的状态。但是,从技术层面它们有明显的区别:遗嘱消息是在connect时设置的;保留消息是在pushlish消息时指定的。

演示遗嘱消息

为了实现 MQTT 连接被异常断开的效果,我们需要调整一下 EMQX 的默认 ACL 规则与相关配置项:

首先在 etc/acl.conf 中添加以下 ACL 规则,表示拒绝本机客户端连接发布 test 主题。注意需要加在所有默认 ACL 规则之前,以确保这条规则能成功生效:

{deny, {ipaddr, "127.0.0.1"}, publish, ["test"]}.

然后修改 etc/emqx.confzone.internal.acl_deny_action 配置项,将其设置为 ACL 检查拒绝时断开客户端连接:

zone.internal.acl_deny_action = disconnect

完成以上修改后,我们启动 EMQX。

接下来,我们在 MQTT X 中新建一个名为 demo 的连接,Host 修改为 localhost,在 Advanced 部分选择 MQTT Version 为 5.0,并且将 Session Expiry Interval 设置为 10,确保会话不会在遗嘱消息发布前过期。

然后在 Lass Will and Testament 部分将 Last-Will Topic 设置为 offline,Last-Will Payload 设置为 I'm offline,Will Delay Interval (s) 设置为 5。

完成以上设置后,我们点击右上角的 Connect 按钮以建立连接。

然后我们再创建一个名为 subscriber 的客户端连接,并订阅 offline 主题。

接下来我们回到 demo 连接中,发布一个 Topic 为 test 的任意内容消息,这时连接会被断开,耐心等待五秒钟,我们将看到 subscriber 连接收到了一条内容为 I‘m offline 的遗嘱消息。

进阶使用场景

这里介绍一下如何将 Retained 消息与 Will 消息结合起来进行使用。

  1. 客户端 A 遗嘱消息内容设定为 offline,该遗嘱主题与一个普通发送状态的主题设定成同一个 A/status
  2. 当客户端 A 连接时,向主题 A/status 发送内容为 online 的 Retained 消息,其它客户端订阅主题 A/status 的时候,将获取到 Retained 消息为 online
  3. 当客户端 A 异常断开时,系统自动向主题 A/status 发送内容为 offline 的消息,其它订阅了此主题的客户端会马上收到 offline 消息;如果遗嘱消息设置了 Will Retain,那么此时如果有新的订阅 A/status 主题的客户端上线,也将获取到内容为 offline 的遗嘱消息。

消息传输质量保障

在 MQTT 协议中,消息分为 3 个等级,分别用 QoS0, QoS1, QoS2, 这三个不同的 QoS 值所代表的是不同的服务质量等级。以下是每一个服务质量级别的具体描述:

  • 0 : 最多一次发送(若消息等级为 QoS 0,发布者在发布消息时只会发送一次,不管消息是否送达);
  • 1 : 至少一次消息发送(若消息等级为 QoS 1,发布者在发布消息时会重复发送以确保消息发送成功);
  • 2 : 消息只发送一次,并保证送达。(若消息等级为 QoS 2, 发布者在发布消息时确保接收者只接收到一个消息并且消息不会重复)。

在三种 QoS 消息等级中,QoS 0 是最节省计算资源的, 而 QoS 1 在发布完消息后还需要去接收到一个发布确认报文来停止重复的报文发送, QoS 2 消息的传输则需要更多的步骤,它需要 4 次报文发送来确保消息是单次送达的,是所有消息类型中最费计算资源和带宽的。

QoS 0 消息

在 MQTT 3.0 中,QoS 0 的消息发布流程是这样

发送者 控制报文流向 接受者
PUBLISH QoS = 0, DUP = 0
—>
接收消息(可能不会收到)并处理

QoS 1 消息

发送者 控制报文流向 接受者
存储消息
发送 PUBLISH QoS1, DUP = 0,带有 Packetld —>
接收消息并处理
发送带有 Packetld 和 PUBACK 确认报文
丢弃消息

若接收者没有接收到 QoS1 消息或者接收到的 QoS 1 消息有问题,是不会去发送 PUBACK 确认报文的,因此发送者不会丢弃 QoS1 消息,它还会再发送这个消息,所以 QoS1 消息是有可能被重复发布的。

QoS 2 消息

发送者 控制报文流向 接受者
存储消息
发送 PUBLISH QoS1, DUP = 0,带有 Packetld
—>
存储 Packet ID 然后准备应用消息的发送
发布带有 Packetld 和 Reason Code 的 PUBREC 报文
<—
丢弃存储的消息,存储接收到的带有相同 packet ID 的 PUBREC 报文
发送 PUBREC 报文 —> 丢弃 Packetld
发送带有 Packetld 的 PUBCOMP 报文
<—
丢弃存储的状态

为了保证消息单次发送且能送达。首先它要发布一个 PUBLISH 报文,然后接收者在接收完成时并不会返回确认报文,它会存储接收到的消息,然后返回 PUBREC 报文给发送者,发送者在接收到 PUBREC 报文后, 将存储的 PUBLISH 报文替换成收到的 PUBREC 报文,然后发送 PUBREL 报文给接收者。 接收者收到 PUBREL 消息后丢弃之前存储的状态,此时消息已经到达接收者,并且能够确保只到达了一次。

模糊订阅

MQTT协议提供订阅主题模糊匹配的规则,这样子客户端可以指定匹配规则,订阅一类消息,从而提高了MQTT 客户端的业务处理能力。

MQTT 主题通配符包含单层通配符 + 及多层通配符 #,主要用于客户端一次订阅多个主题。注意:通配符只能用于订阅,不能用于发布。

主题规则

MQTT 主题本质上是一个 UTF-8 编码的字符串,是 MQTT 协议进行消息路由的基础。MQTT 主题类似 URL 路径,使用斜杠 / 进行分层:

chat/room/1
sensor/10/temperature
sensor/+/temperature
sensor/#

为了避免歧义且易于理解,通常不建议主题以 / 开头或结尾,例如 /chatchat/

单层通配符

加号 (“+” U+002B) 是用于单个主题层级匹配的通配符。在使用单层通配符时,单层通配符必须占据整个层级,例如:

+ 有效
sensor/+ 有效
sensor/+/temperature 有效
sensor+ 无效(没有占据整个层级)

如果客户端订阅了主题 sensor/+/temperature,将会收到以下主题的消息:

sensor/1/temperature
sensor/2/temperature
...
sensor/n/temperature

但是不会匹配以下主题:

sensor/temperature
sensor/bedroom/1/temperature

多层匹配符

井字符号(“#” U+0023)是用于匹配主题中任意层级的通配符。多层通配符表示它的父级和任意数量的子层级,在使用多层通配符时,它必须占据整个层级并且必须是主题的最后一个字符,例如:

# 有效,匹配所有主题
sensor/# 有效
sensor/bedroom# 无效(没有占据整个层级)
sensor/#/temperature 无效(不是主题最后一个字符)

如果客户端订阅主题 senser/#,它将会收到以下主题的消息:

sensor
sensor/temperature
sensor/1/temperature

共享订阅

共享订阅是 MQTT 5.0 引入的新特性,用于在多个订阅者之间实现订阅的负载均衡,MQTT 5.0 规定的共享订阅主题以 $share 开头。

虽然 MQTT 协议在 5.0 版本才引入共享订阅,但是 EMQX 从 MQTT 3.1.1 版本开始就支持共享订阅。

下图中,3 个订阅者用共享订阅的方式订阅了同一个主题 $share/g/topic,其中topic 是它们订阅的真实主题名,而 $share/g/ 是共享订阅前缀(g/ 是群组名,可为任意 UTF-8 编码字符串)。

WS 客户端发送向share_topic 发送消息,发送四条数据,数据下标从message0 至 message3


如上所示,两个订阅方分别消费了一部分数据。目前EMQX官方提供的共享策略为:

  • random: 在所有共享订阅会话中随机选择一个发送消息,为默认的共享策略。
  • round_robin: 按照订阅顺序轮流选择
  • sticky: 使用 random 策略随机选择一个订阅会话,持续使用至该会话取消订阅或断开连接再重复这一流程
  • hash: 对发送者的 ClientID 进行 hash 操作,根据 hash 结果选择订阅会话

MQTT协议 EMQX服务器安装、测试相关推荐

  1. MQTT协议-报文分析及网络客户端报文测试(MQTT报文连接阿里云上传数据+订阅数据)

    文章目录 一.本文章所涉及到的内容 二.感性认识MQTT协议 三.准备信息 (一)工具获取 (二)获取信息 1.获取三元组信息 2.获取发布topic和订阅topic 3.客户端ID,用户名,哈希加密 ...

  2. mqtt协议调用示例(包括MQTT一键启动服务+测试工具 MQTTFX云盘下载),对捷顺门禁温感一体机进行人员信息下发

    hello, 大家好 我是一只不是在戏精,就是在戏精路上的极品二哈 新年上班第一天,给大家贡献一篇 MQTT 协议使用示例文章 也是本汪自己的一篇实用笔记 本汪先总的说下: MQTT协议进行数据交互, ...

  3. mqtt协议与emqx相关使用

    MQTT协议 直接照着百度相关内容可以看出来,mqtt协议其实就是一个及时通讯协议,跟rocketMQ类似,也可以说是一个消息中间件. 作为一个传递消息的协议,mqtt是基于一个"发布者-& ...

  4. mqtt协议 及emqx,mosquitto的一点看法

    1)MQTT协议和其它协议的区别 MQTT是 OSI 的 第7层,应用层协议,和HTTP(S)/FTP/POP3/DNS/TELNET等处于同一级别(楼最高). Socket是第5层,会话层 TCP/ ...

  5. MQTT协议测试工具及核心代码

    基于MQTTnet做了个MQTT协议测试程序,本程序包括服务的和两个客户端,方便在不引入外部支撑的情况下测试MQTT协议. 测试软件界面如下 1:启动MQTT服务 在Server区域, 启动服务可以选 ...

  6. 【EMQX 5.0】1.1 MQTT协议介绍

    1.1  MQTT协议介绍         随着 5G 时代的来临,万物物联的伟大构想正在成为现实.联网的物联网设备在 2018 年已经达到了 70 亿, 在未来两年,仅智能水电气表就将超过10 亿. ...

  7. 【EMQX 5.0】1.3 MQTT协议数据包结构

    1. MQTT数据包         官方文档: http://mqtt.org/documentation          MQTT数据包 由以下 三部分构成 : 固定头(Fixed header ...

  8. 001-STM32+BC26/260Y基本控制篇(自建物联网平台)--基础知识-MQTT协议

    先来体验一下MQTT通信 1.提示: 可以把MQTT软件安装到自己的电脑,也可以安装在云服务器上 如果把MQTT服务器安装在自己的电脑上,连接服务器的IP地址就是自己电脑的IP地址 如果安装到云服务器 ...

  9. 提交客户端证书_MQTT X v1.3.3 正式发布 - 跨平台 MQTT 5.0 桌面测试客户端

    MQTT X 是由全球领先的开源物联网中间件提供商 EMQ 开源的一款跨平台 MQTT 5.0 桌面测试客户端,它支持 macOS,Linux,Windows.MQTT X 的用户界面借助聊天软件的形 ...

最新文章

  1. win32文件读写demo
  2. 在Spring中使用JTA事务管理
  3. boost::mp11::mp_cond相关用法的测试程序
  4. python语言有哪两个系列_(转)Python学习笔记系列——Python是一种纯粹的语言
  5. Django05-2:路由分发/命名空间/伪静态/虚拟环境/django版本区别
  6. hdc mfc 画扇形图_MFC画图总结-DIB图形绘制
  7. Kubernetes之(五)快速部署应用
  8. windows查看usb信息命令_ADB命令你知道多少?ADB冻结系统应用?
  9. HTML注册页面的设计
  10. gallery3d 代码分析
  11. JetBrains DataGrip 2018.2.3中文破解版 含jar文件注册码激活教程(转)
  12. c语言程序最简单例子,简单C语言程序的例子
  13. Flex Builder3编译时生成as
  14. 搜狗输入法纯净_五款良心无广告的纯净输入法推荐
  15. 取绝对值 :abs fabs fabsf用法
  16. 13.6.1 PDF 偏执狂
  17. 【验证码逆向专栏】某片滑块、点选验证码逆向分析
  18. 网易云音乐的歌单推荐算法是怎样的?
  19. 高速光耦(PS8101,TLP112A,TLP109)基本工作原理应用实例
  20. 用matlab绘制克莱因瓶,完美!年前学会SketchUp建模克莱因瓶

热门文章

  1. 宇视录像机通道名称如何修改
  2. IT桔子IT互联网公司产品数据库及商业信息服务
  3. Project 的简单使用
  4. 网址最后面不带斜杠与带斜杠有什么区别
  5. 基于ESP8266称重式压力传感器(接入阿里云物联网平台)
  6. 一个女大学生骂她男朋友的话,厉害,没一个脏字
  7. 喜剧院线电影《大夫我没病》在京开机
  8. 用Python实现自动扫雷
  9. python手机壁纸超清_Python爬虫-王者荣耀高清壁纸下载
  10. 超快激光微加工的Burst Mode和PSO功能