资讯专栏INFORMATION COLUMN

【如何构建商业级别聊天系统】 MQTT 篇(四)MQTT 特性之 持久会话、保留消息、遗嘱

LancerComet / 3028人阅读

摘要:如何构建商业级别聊天系统篇四特性之持久会话保留消息遗嘱本篇将介绍的一些我们应该关注的特性关注不迷路我是搁浅神秘地址持久会话为什么需要持久会话为了接收的消息,客户端在连接时会创建其感兴趣主题的订阅。代理仅存储每个主题的一条保留消息。

【如何构建商业级别聊天系统】 MQTT 篇(四)MQTT 特性之 持久会话、保留消息、遗嘱

本篇将介绍 MQTT 的一些我们应该关注的特性
关注不迷路!! 我是 dying 搁浅 神秘地址

1. 持久会话

为什么需要持久会话?

为了接收 MQTT broker 的消息,客户端在连接 broker 时会创建其感兴趣主题的订阅。当客户端和代理的连接在非持久会话中断开时,这些主题将丢失,这意味着客户端在重新连接需要重新订阅,这对于资源受限的客户端来说是一笔很高的消耗。同时我们在大多数业务场景下都需要保存一个持久的会话来记录客户端的状态(如保存在 DB 中)。那么将会话的状态等信息保存到代理 broker 中就是一个很好的选择。在客户端与服务代理建立连接时根据唯一的标识来提供会话的信息(如登录凭证或者 clientId)

持久会话存储什么?
  • session 信息,客户端凭证
  • 客户端所有订阅信息
  • 所有客户端未确认的 QoS 级别为 1 或者 2 的消息
  • 客户端在离线时所有错过的 QoS 级别为 1 或者 2 的消息
  • 所有从客户端收到,尚未完全确认的 QoS 2 的消息
那么如何开始或者结束一个持久会话?

客户端可以通过 cleanSession 进行标记,来告诉 broker 代理自己需要怎样的会话,在与代理建立连接时可以选择请求持久会话。

cleanSession = true 非持久会话 如果客户端请求非持久会话,那么当客户端与代理断连时其前一个持久会话的所有排队消息都将丢失。

cleanSession = false 持久会话 如果客户端请求持久会话,代理服务端将保存会话的所有信息

最佳实战

这里我们将会话分为: persistent session 持久会话clean session 清洁会话

何时使用 持久会话

  • 客户端必须从某个主题获取所有消息,即使其离线,也想通过 broker 进行消息排队,以便重新连接后立即传送他们。
  • 客户端资源有限,希望通过代理存储其订阅消息,并快速恢复中断的通信。
  • 客户端需要在重新连接后恢复所有 qos 1 或者 2 的消息。

何时使用 清洁会话

  • 客户端只需要发布消息,不需要订阅主题。客户端不希望 broker 存储消息或者重试 qos 1 或者 2 的传输。
  • 客户端不需要获取离线错过的消息。

2. 保留消息

为什么需要保留消息?

对于 消息发布者 和 主题订阅者,双方对于相互的状态是无感知的,因为我们的 broker 代理 代理了这一切,那么消息发布者只能确保消息正确的发送到了 broker 代理,而 broker 代理 和 主题订阅者之间同样如此。而 消息发布者 并不确定何时向对应的主题发布消息,那在这期间,新订阅主题的客户端对该主题的状态一无所知。这个时候,保留消息就起到的它的作用。

什么是保留消息?

保留消息 是 一条普通的 MQTT 消息 其 retained flag 设置为 true,broker 代理为主题存储其最后一条保留消息以及其 Qos 级别。

那么每个订阅匹配该主题的客户端在订阅后将立即收到该条 保留消息。代理仅存储每个主题的一条保留消息。

订阅客户端 可以通过 retained flag 来识别该条消息是否为 保留消息,以便决定如何处理它。

保留消息的作用

保留消息可以帮助 新订阅的客户端 立即获得该主题的状态更新,其消除了等待 发布客户端 发布下一条消息的时间间隔。

最佳实战

啊,那么我们什么时候应该使用保留消息呢?当你希望新订阅的客户端立即获取主题消息时,保留消息是有意义的

这对于单个组件主题的状态更新非常有用,例如 /my/temperature 获取温度状态,如果使用保留消息,新订阅者在订阅时将立即获取最后的温度状态。如果没有使用,那么在发布者发布下一条消息期间,新订阅者将处于黑暗状态

3.遗嘱

为什么需要遗嘱?

MQTT 经常构建于不可靠的网络场景,由于连接丢失,电量耗尽,可能会发生异常断开的情况。了解客户端是 正常断开(MQTT DISCONNECT 消息) 还是 异常断开 有助于我们进行正确的响应,这里遗嘱消息就发挥了作用。

LWT 最后的遗嘱 Last Will and Testament

在 MQTT 中使用 LWT 最后的遗嘱来通知 其他客户端 异常断开的情况。每个客户端在连接到代理时,可以指定 LWT

LWT 是一条普通的 MQTT 消息带有 主题、保留消息标志、QoS 和 payload。代理保存该消息直到客户端异常断开,此时代理会将 LWT 消息发送给每个订阅该主题的客户端。当客户端正常断开时,LWT 消息会被代理直接丢弃。

如何指定 LWT?

在客户端 CONNECT 时,客户端可以指定一条 LWT 消息

代理应该在何时发送 LWT 消息?

根据 MQTT 规范,borker 代理 必须在以下情况分发 客户端 LWT 消息:

  • 代理检测到 I/O 错误或者网络故障
  • 客户端无法再定义的 Keep Alive 时间内进行通信
  • 客户端在关闭网络连接之前不会发送 DISCONNECT 数据包
  • 由于协议错误,代理关闭连接

最佳实战

最后的遗嘱 LWT 是通知订阅客户端,发布客户端异常断开的有效手段。其在生产上经常和 保留消息一起配合使用,以存储客户端在特定主题上的状态。

举个例子:client1 首先向 broker 发送 CONNECT 数据包其中

lastWillMessage 将 ”offline“ 作为 payload

lastWillRetain 设置为 true

lastWillTopic 设置为 client1/status

连接之后 client1 再向主题发送一条 PUBLISH 消息,其 payload 为 ”online“ 并将其 retain flag 设置为 true。

此时 只要 client1保持连接,那么所有新订阅主题的客户端都会收到一条 ”online“ 消息。

如果 client1 异常断开,broker 会给所有订阅客户端发送 ”offline“ 的 LWT 消息,同时 LWT 消息会成为新的保留消息发送给新的订阅者。

这种特定的保留消息模式,可以让其他客户端知道,client1 在特定主题上的连接状态。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/118877.html

相关文章

  • 如何构建商业级别聊天系统MQTT (五)保活 Keep Alive,请不要让你的 MQTT

    摘要:如何构建商业级别聊天系统篇五保活,请不要让你的服务变成小猪佩奇特关人上人搁浅神秘连接哥哥姐姐弟弟妹妹叔叔阿姨们说点闲话保活,不光是对于来说需要保活,其实我们很多的系统,在需要确定对方是否处于可通信状态的时候都是需要这种保活机制。 ...

    aboutU 评论0 收藏0
  • MQTT协议介绍

    摘要:协议简介,消息队列遥测传输是一个轻量的发布订阅模式消息传输协议,是专门针对低带宽和不稳定网络环境的物联网应用设计的。它是等级协议交换的第二个报文。 1.MQTT协议简介 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是一个轻量的发布/订...

    lewinlee 评论0 收藏0
  • MQTT

    摘要:协议版本介绍互联网的基础网络协议是协议消息队列遥测传输是基于协议栈而构建的已成为通信的标准为什么选择有多好多好多么牛逼我就不说了说的再多不如一个一个试试完了做比对剩下的那个就是要选择的实在不想这样搞技术就跟着一线走发布和订阅模型协议在网络中 mqtt 协议版本: 3.1.1 MQTT 介绍 互联网的基础网络协议是 TCP/IP协议. MQTT(消息队列遥测传输)是基于 TCP/IP 协...

    lastSeries 评论0 收藏0
  • 基于MQTT的物联网云测量解决方案

    摘要:本文是其中的一个解决方案。地址客户端服务端前端网页介绍,消息队列遥测传输是开发的一个即时通讯协议,有可能成为物联网的重要组成部分。必须用于在顶层分隔符之后,除了当自己指定时。 1. 问题描述 最近,本实验室大量上马云测量,云监控方面的项目,大概是属于物联网应用的一个分支。老板也有将旧有仪器改造的想法,所以要实现仪器设备的云控制。本文是其中的一个解决方案。 2. 技术选型 消息队列:M...

    张金宝 评论0 收藏0
  • ESP32学习笔记(46)——MQTT客户端

    摘要:一简介实现方式实现协议需要客户端和服务器端通讯完成,在通讯过程中,协议中有三种身份发布者代理服务器订阅者。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。 ...

    Jenny_Tong 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<