LWT 全称为 Last Will and Testament,也就是我们在连接到 Broker 时提到的遗嘱,包括遗嘱Topic、遗嘱 QoS、遗嘱消息等。

顾名思义,当 Broker 检测到 Client 非正常地断开连接的时候,就会向遗嘱Topic里面发布一条消息。遗嘱相关的设置是在建立连接的时候,在 CONNECT 数据包里面的 Variable header(可变头与) Payload(有效载荷) 中 指定的。

  • Will Flag:是1否0使用 LWT
  • Will Topic:遗嘱主题名,不可使用通配符(在 CONNECT报文中的 有效载荷 中 设置)
  • Will Qos:发布遗嘱消息时使用的 QoS 等级,如果遗嘱标志(Will Flag)被设置为0,遗嘱QoS也必须设置为0(0x00)
  • Will Retain:遗嘱消息的 Retain 标识
  • Will Message:遗嘱消息内容(在 CONNECT报文中的 有效载荷 中 设置)

Broker 在以下情况下认为 Client 是非正常断开连接的:

  • Broker 检测到底层的 I/O 异常;
  • Client 未能在 Keep Alive 的间隔内和 Broker 之间有消息交互;
  • Client 在关闭底层 TCP 连接前没有发送 DISCONNECT 数据包;
  • Broker 因为协议错误关闭和 Client 的连接,比如 Client 发送了一个格式错误的 MQTT 数据包。

如果 Client 通过发布 DISCONNECT 数据包断开连接,这个属于正常断开连接,不会触发 LWT 的机制,同时,Broker 还会丢弃掉这个 Client 在连接时指定的 LWT 参数。

使用场景

在客户端 A 进行连接时候,遗嘱消息设定为”offline“,客户端 B 订阅这个遗嘱主题。当 A 异常断开时,客户端 B 会收到这个”offline“的遗嘱消息,从而知道客户端 A 离线了。

Connect Flag 报文字段

Bit 7 6 5 4 2 1 0
  User Name Flag Password Flag Will Retain Will QoS Will Flag Clean Start Reserved
byte 8 X X X X X X X

遗嘱消息在客户端正常调用 disconnect 方法之后并不会被发送。

Will Flag 作用

简而言之,就是客户端预先定义好,在自己异常断开的情况下,所留下的最后遗愿(Last Will),也称之为遗嘱(Testament)。这个遗嘱就是一个由客户端预先定义好的主题和对应消息,附加在CONNECT的可变报文头部中,在客户端连接出现异常的情况下,由服务器主动发布此消息。

当Will Flag位为1时,Will QoS和Will Retain才会被读取,此时消息体中要出现Will Topic和Will Message具体内容,否则Will QoS和Will Retain值会被忽略掉。

当Will Flag位为0时,则Will Qos和Will Retain无效。

命令行示例

下面是一个Will Message的示例:

  1. Sub端clientid=sub预定义遗嘱消息:

    mosquitto_sub --will-topic test --will-payload die --will-qos 2 -t topic -i sub -h 192.168.1.1
    
  2. 客户端 clientid=alive 在 192.168.1.1(EMQ服务器) 订阅遗嘱主题

    mosquitto_sub -t test -i alive -q 2 -h 192.168.1.1
    
  3. 异常断开Sub端与Server端(EMQ服务器)连接,Pub端收到Will Message 。

根据遗嘱的属性和触发机制,我们不难看出,遗嘱常用于获取设备的连接状态。

注意,设置好遗嘱以后还不够(因为你只要订阅者一启动就会收到遗嘱消息,如果此时发布者已经在线,会导致不准确),
所以,还需要在设备成功连接MQTT的时候主动发个消息,发送的主题必须和遗嘱的主题相同,设置好消息的 retain 属性,让其自动纠正过来。

最佳使用:

我想让我的APP或者上位机或者网页一登录的时候获取设备的状态   在线还是离线

设备端只需要这样设置

注意:MQTT本身有遗嘱设置

所以大家可以设置遗嘱 ,注意哈,发布的主题自己随意哈,假设是aaaaa  假设设置的遗嘱是   {data:state,state:offline}   注意遗嘱的retain 必须设置为1 ,即让服务器保留这个消息

如果这样设置了,那么只要 设备掉线了,服务器就会向订阅aaaaa主题的APP或者上位机或者网页发送{data:state,state:offline}

但是只这样设置还不行,因为你会发现每次APP或者上位机或者网页只要一启动就会收到{data:state,state:offline}

所以需要下一步

在设备成功连接MQTT的时候主动发个消息,发送的主题必须和上面一样哈aaaaa  假设消息是 {data:state,state:online}  注意消息的retain 必须设置为1 ,即让服务器保留这个消息

Mqtt Will Message(遗嘱消息)相关推荐

  1. MQTT 遗嘱消息(Will Message)的使用

    简介 当客户端断开连接时,发送给相关的订阅者的遗嘱消息.以下情况下会发送 Will Message: 服务端发生了I/O 错误或者网络失败: 客户端在定义的心跳时期失联: 客户端在发送下线包之前关闭网 ...

  2. MQTT C Client实现消息推送(入门指南)

    我自己搭建了博客,以后可能不太在CSDN上发博文了,https://www.qingdujun.com/ . MQTT(Message Queuing Telemetry Transport,消息队列 ...

  3. [Java]SpringBoot2整合mqtt服务器EMQ实现消息订阅发布入库(二)

    又到了显摆分享技术的时候了 没有看过上一篇文章的可以先看一下,这篇是在上一篇基础上接着添加功能 SpringBoot2整合mqtt服务器EMQ实现消息订阅发布入库(一) 这篇文章的流程为: 1.Spr ...

  4. 基于RabbitMQ 的 Web MQTT插件进行前端消息实时推送

    目录 RabbitMQ What is AMQP, MQTT, STOMP ? How to use RabbitMQ with MQTT ? 1. Docker 安装RabbitMQ 2. MQTT ...

  5. Windows Azure NotificationHub+Firebase Cloud Message 实现消息推动(付源码)

    前期项目一直用的是Windows azure NotificationHub+Google Cloud Message 实现消息推送, 但是GCM google已经不再推荐使用,慢慢就不再维护了, 现 ...

  6. 什么是JMS(Java Message Service消息服务)

    JMS的定义 JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息 ...

  7. Message Bus - 消息总线

    Message Bus - 消息总线 Liferay的*消息总线(Message Bus)*是一种服务级API,组件可以用它来发送和接收消息.它提供了消息生产者(producers)和消费者(cons ...

  8. MQTT接受未订阅消息

    记录个人遇到mqtt接受未订阅消息问题 示例: 我只订阅了一个:abc主题 但是接受消息时,接受到了其他主题消息,查看代码后也未发现问题 Attention 可能是你之前已经订阅过该主题消息,但是没有 ...

  9. MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)协议

    简介 mqtt有IBM公司开发,90年代的产物. 解决了如下问题:服务器必须要实现成千上万的接入:单词数据量小,不能出错:必须能够使用高延迟.偶尔断网等通信不可靠的风险:根据数据的重要程度和特性,设置 ...

最新文章

  1. 关于cgroup的几个核心名词及其关系
  2. Java中如何实现线程的超时中断
  3. 计算机二级网址打不开,大神为你解决win7系统打不开二级网页链接的操作教程...
  4. hdu 1536(博弈)
  5. mysql 自增id replace_MySQL--REPLACE INTO与自增
  6. java 如何去掉http debug日志_Spring Boot手把手教学(3):从零配置logback日志
  7. 转https_这个PDF转图片技巧,不用1分钟就能快速上手
  8. python打包成exe fail to ex_寻求帮助:pyinstaller打包.exe
  9. java IO之字节流和字符流-OutputSteam和InputStream
  10. C++宠物商店管理系统
  11. 一款非常优秀的内存数据库——lmdb
  12. 安装window10出错:选中的磁盘具有 MBR 分区表。在 EFI 系统上,Windows只能安装到GPT磁盘。
  13. win7计算机摄像头怎么打开,告诉你win7如何打开摄像头
  14. python导入包如果找不到
  15. 啊哈算法-DFS解救小哈python版
  16. HDUOJ 6441 Find Integer
  17. 年末巨献|大数据盛会!企业大数据落地高峰论坛倒计时,速速报名!
  18. 我用Python分析1585家电商车厘子销售数据,发现这些秘密!
  19. 在python中_语法-和在Python中是什么意思?
  20. 44.求Sn=a+aa+aaa+aaaa+aaaaa的前5项之和

热门文章

  1. openldap自主密码修改平台实现
  2. list组件设置flex-direction:row之后,设置的高度不生效
  3. R语言data.frame label的设置
  4. 常规网站改版是否对搜索引擎友好?
  5. 谷歌与Oracle:Java版权大战现在牵扯到美国总统奥巴马
  6. 机器学习:鸢尾花(Iris)分类
  7. go iris 源码思路分析
  8. Linux安装expect
  9. 笔记——流水线基础概念
  10. 异常处理try_except-else-finally