我的mqtt协议和emqttd开源项目个人理解(25) - 协议里面Clean Session为0和1的区别

简介: 我的mqtt协议和emqttd开源项目个人理解(25) - 协议里面Clean Session为0和1的区别

一、基本概念


Session 会话


定义


定义:某个客户端(由ClientID作为标识)和某个服务器之间的逻辑层面的通信

生命周期(存在时间):会话 >= 网络连接

CleanSession 标记

在Connect时,由客户端设置

0 —— 开启会话重用机制。网络断开重连后,恢复之前的Session信息。需要客户端和服务器有相关Session持久化机制。

1 —— 关闭会话重用机制。每次Connect都是一个新Session,会话仅持续和网络连接同样长的时间。



客户端 Session

已经发送给服务端,但是还没有完成确认的 QoS 1 和 QoS 2 级别的消息

已从服务端接收,但是还没有完成确认的 QoS 2 级别的消息



服务器端 Session

会话是否存在,即使会话状态的其它部分都是空  (SessionFlag)

客户端的订阅信息  (ClientSubcription)

已经发送给客户端,但是还没有完成确认的 QoS 1 和 QoS 2 级别的消息

即将传输给客户端的 QoS 1 和 QoS 2 级别的消息

已从客户端接收,但是还没有完成确认的 QoS 2 级别的消息

(可选)准备发送给客户端的 QoS 0 级别的消息


二、关于协议的问答


问:问个mqtt协议的问题,cleansession为什么要区别0和1,他们各自的用途和应用场景是什么?


答:为 1 的时候,服务器每次session 都要重新建立,这也是大多数的场景使用情况;


为 0 的时候可以复用历史的session, 服务端session 是有状态的,可以记录很多信息。


为 0的时候就可以保留 session 了,这个保留的session 是有用的,如果服务端实现了的话,像历史没发出去的消息等等,鉴权信息,等等,可以接着使用。你可以类比我们登陆网页的那个session,没过期的话,可以不用登陆了。


说白了,想接收离线消息,就必须使用cleansession=0,这个就是=0的应用场景:


不管clean session的值是什么,当终端设备离线时,QoS=0,1,2的消息一律接收不到。

当clean session的值为1,当终端设备离线再上线时,离线期间发来QoS=0,1,2的消息一律接收不到。

当clean session的值为0,当终端设备离线再上线时,离线期间发来QoS=0,1,2的消息仍然可以接收到。如果同个主题发了多条就接收多条,一条不差,照单全收。


三、emq源码里面,hook上下线流程


1、emq v2当服务器进程重启之后,session会清除掉,没有实现本地持久化。


2、cleansession为0和1的时候,hook里面的上下线,0和1流程大不相同。相同clientid冲突登录。


以下的打印信息来自hook插件源码文件

emqttd:hook('client.connected', fun ?MODULE:on_client_connected/3, [Env]),

emqttd:hook('client.disconnected', fun ?MODULE:on_client_disconnected/3, [Env]),

emqttd:hook('session.created', fun ?MODULE:on_session_created/3, [Env]),

emqttd:hook('session.terminated', fun ?MODULE:on_session_terminated/4, [Env]),


(1)、cleansession==1的情况

场景1,客户端自身上线下线

正常上线

session(firecat_heartbeat001/firecatGTerm) created.

client firecat_heartbeat001 connected, connack: 0

正常下线

client firecat_heartbeat001 disconnected, reason: normal

session(firecat_heartbeat001/firecatGTerm) terminated: normal.


场景2,客户端先正常上线,后相同clientid客户端在别的地方又上线,造成clientid冲突

先正常上线

session(firecat_heartbeat001/firecatGTerm) created.

client firecat_heartbeat001 connected, connack: 0

后冲突上线

session(firecat_heartbeat001/firecatGTerm) terminated: {shutdown,conflict}.

session(firecat_heartbeat001/firecatGTerm) created.

client firecat_heartbeat001 connected, connack: 0

注意,冲突上线,后者会把前者挤掉,但是前者不会触发离线函数,仅仅把session毁掉重建而已.

后者正常下线

client firecat_heartbeat001 disconnected, reason: normal

session(firecat_heartbeat001/firecatGTerm) terminated: normal.



(2)、cleansession==0的情况

场景1,客户端自身第一次上线下线

正常上线

session(firecat_heartbeat001/firecatGTerm) created.

client firecat_heartbeat001 connected, connack: 0

正常下线

client firecat_heartbeat001 disconnected, reason: normal

注意,这里不销毁session

最终,session会有过期时间,时间到会销毁,时间(貌似2个小时?)详见emqttd_session.erl

session(firecat_heartbeat001/firecatGTerm) terminated: {shutdown,expired}.


场景2,客户端自身第N次(N>1)上线下线

正常上线

注意,这里不创建session

client firecat_heartbeat001 connected, connack: 0

正常下线

client firecat_heartbeat001 disconnected, reason: normal

注意,这里不销毁session

最终,session会有过期时间,时间到会销毁,时间详见emqttd_session.erl

session(firecat_heartbeat001/firecatGTerm) terminated: {shutdown,expired}.


场景3,客户端先正常上线,后相同clientid客户端在别的地方又上线,造成clientid冲突

先正常上线

session(firecat_heartbeat001/firecatGTerm) created.

client firecat_heartbeat001 connected, connack: 0

后冲突上线

client firecat_heartbeat001 connected, connack: 0

注意,冲突上线,后者会把前者挤掉,但是前者不会触发离线函数,session也不毁掉不重建.

后者正常下线

client firecat_heartbeat001 disconnected, reason: normal

注意,这里不销毁session

最终,session会有过期时间,时间到会销毁,时间详见emqttd_session.erl

session(firecat_heartbeat001/firecatGTerm) terminated: {shutdown,expired}.

 


相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
26天前
|
消息中间件 存储 监控
ActiveMQ、RocketMQ、RabbitMQ、Kafka 的区别
【10月更文挑战第24天】ActiveMQ、RocketMQ、RabbitMQ 和 Kafka 都有各自的特点和优势,在不同的应用场景中发挥着重要作用。在选择消息队列时,需要根据具体的需求、性能要求、扩展性要求等因素进行综合考虑,选择最适合的消息队列技术。同时,随着技术的不断发展和演进,这些消息队列也在不断地更新和完善,以适应不断变化的应用需求。
70 1
|
1月前
|
网络协议 物联网 网络性能优化
物联网协议比较 MQTT CoAP RESTful/HTTP XMPP
【10月更文挑战第18天】本文介绍了物联网领域中四种主要的通信协议:MQTT、CoAP、RESTful/HTTP和XMPP,分别从其特点、应用场景及优缺点进行了详细对比,并提供了简单的示例代码。适合开发者根据具体需求选择合适的协议。
53 5
|
1月前
|
消息中间件 存储 监控
说说如何解决RocketMq消息积压?为什么Kafka性能比RocketMq高?它们区别是什么?
【10月更文挑战第8天】在分布式系统中,消息队列扮演着至关重要的角色,它不仅能够解耦系统组件,还能提供异步处理、流量削峰和消息持久化等功能。在众多的消息队列产品中,RocketMQ和Kafka无疑是其中的佼佼者。本文将围绕如何解决RocketMQ消息积压、为什么Kafka性能比RocketMQ高以及它们之间的区别进行深入探讨。
85 1
|
2月前
|
消息中间件 监控 物联网
MQTT协议对接及RabbitMQ的使用记录
通过合理对接MQTT协议并利用RabbitMQ的强大功能,可以构建一个高效、可靠的消息通信系统。无论是物联网设备间的通信还是微服务架构下的服务间消息传递,MQTT和RabbitMQ的组合都提供了一个强有力的解决方案。在实际应用中,应根据具体需求和环境进行适当的配置和优化,以发挥出这两个技术的最大效能。
181 0
|
3月前
|
消息中间件 存储 监控
RabbitMQ、Kafka对比(超详细),Kafka、RabbitMQ、RocketMQ的区别
RabbitMQ、Kafka对比(超详细),Kafka、RabbitMQ、RocketMQ的区别,设计目标、适用场景、吞吐量、消息存储和持久化、可靠性、集群负载均衡
RabbitMQ、Kafka对比(超详细),Kafka、RabbitMQ、RocketMQ的区别
|
3月前
|
物联网 C# 智能硬件
智能家居新篇章:WPF与物联网的智慧碰撞——通过MQTT协议连接与控制智能设备,打造现代科技生活的完美体验
【8月更文挑战第31天】物联网(IoT)技术的发展使智能家居设备成为现代家庭的一部分。通过物联网,家用电器和传感器可以互联互通,实现远程控制和状态监测等功能。本文将探讨如何在Windows Presentation Foundation(WPF)应用中集成物联网技术,通过具体示例代码展示其实现过程。文章首先介绍了MQTT协议及其在智能家居中的应用,并详细描述了使用Wi-Fi连接方式的原因。随后,通过安装Paho MQTT客户端库并创建MQTT客户端实例,演示了如何编写一个简单的WPF应用程序来控制智能灯泡。
123 0
|
3月前
|
物联网 网络性能优化 Python
"掌握MQTT协议,开启物联网通信新篇章——揭秘轻量级消息传输背后的力量!"
【8月更文挑战第21天】MQTT是一种轻量级的消息传输协议,以其低功耗、低带宽的特点在物联网和移动应用领域广泛应用。基于发布/订阅模型,MQTT支持三种服务质量级别,非常适合受限网络环境。本文详细阐述了MQTT的工作原理及特点,并提供了使用Python `paho-mqtt`库实现的发布与订阅示例代码,帮助读者快速掌握MQTT的应用技巧。
91 0
|
4月前
|
消息中间件 网络性能优化 开发工具
消息队列 MQ使用问题之MQTT云端和终端的主要区别是什么
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
1月前
|
消息中间件 JSON Java
开发者如何使用轻量消息队列MNS
【10月更文挑战第19天】开发者如何使用轻量消息队列MNS
76 4
|
26天前
|
消息中间件 存储 Kafka
MQ 消息队列核心原理,12 条最全面总结!
本文总结了消息队列的12个核心原理,涵盖消息顺序性、ACK机制、持久化及高可用性等内容。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
下一篇
无影云桌面