MQTT 协议学习:007-Keep Alive 连接保活 与 对应报文(PINGREQ、PINGRESP)
背景
keep alive 是 CONNECT 报文中可变头的一部分。
我们提到过 Broker 需要知道 Client 是否非正常地断开了和它的连接,以发送遗愿消息。实际上 Client 也需要能够很快地检测到它失去了和 Broker 的连接,以便重新连接。
MQTT 协议是基于 TCP 的一个应用层协议,理论上 TCP 协议在丢失连接时会通知上层应用,但是 TCP 有一个半打开连接的问题(half-open connection)。这里我不打算深入分析 TCP 协议,需要记住的是,在这种状态下,一端的 TCP 连接已经失效,但是另外一端并不知情,它认为连接依然是打开的,它需要很长的时间才能感知到对端连接已经断开了,这种情况在使用移动或者卫星网络的时候尤为常见。
所以,仅仅依赖 TCP 层的连接状态监测是不够的,于是 MQTT 协议设计了一套 Keep Alive 机制。回忆一下,在建立连接的时候,我们可以传递一个 Keep Alive 参数,它的单位为秒,MQTT 协议中约定:在 1.5*Keep Alive 的时间间隔内,如果 Broker 没有收到来自 Client 的任何数据包,那么 Broker 认为它和 Client 之间的连接已经断开;同样地, 如果 Client 没有收到来自 Broker 的任何数据包,那么 Client 认为它和 Broker 之间的连接已经断开。
MQTT 还有一对 PINGREQ/PINGRESP 数据包,当 Broker 和 Client 之间没有任何数据包传输的时候,可以通过 PINGREQ/PINGRESP 来满足 Keep Alive 的约定和侦测连接状态。
对于 Keep Alive 机制,我们还需要记住以下几点:
- 如果在一个 Keep Alive 时间间隔内,Client 和 Broker 有过数据包传输,比如 PUBLISH,Client 就没有必要再使用 PINGREQ 了,在网络资源比较紧张的情况下这点很重要;
- Keep Alive 值是由 Client 指定的,不同的 Client 可以指定不同的值;
- Keep Alive 的最大值为 18 小时 12 分 15 秒;
- Keep Alive 值如果设为 0 的话,代表不使用 Keep Alive 机制。
说明
如果没有任何其它的控制报文可以发送,客户端必须发送一个PINGREQ报文。
不管保持连接的值是多少,客户端任何时候都可以发送PINGREQ报文,并且使用PINGRESP报文判断网络和服务端的活动状态。
如果保持连接的值非零,并且服务端在一点五倍的保持连接时间内没有收到客户端的控制报文,它必须断开客户端的网络连接,认为网络连接已断开。
客户端发送了PINGREQ报文之后,如果在合理的时间内仍没有收到PINGRESP报文,它应该关闭到服务端的网络连接。
PINGREQ – 心跳请求 报文
当 Client 在一个 Keep Alive 时间间隔内没有向 Broker 发送任何数据包,比如 PUBLISH 和 SUBSCRIBE 的时候,它应该向 Broker 发送 PINGREQ 数据包。
PINGREQ 数据包没有可变头(Variable header)和消息体(Payload),那么,PINGREQ 报文的全部内容(共2个字节)就是 : 0xc0 0x00
PINGRESP – 心跳响应 报文
当 Broker 收到来自 Client 的 PINGREQ 数据包,它应该回复 Client 一个 PINGRESP 数据包。
PINGRESP 数据包没有可变头(Variable header)和消息体(Payload),那么,PINGRESP 报文的全部内容(共2个字节)就是 : 0xd0 0x00
MQTT 协议学习:007-Keep Alive 连接保活 与 对应报文(PINGREQ、PINGRESP)的更多相关文章
- MQTT 协议学习: 总结 与 各种定义的速查表
		背景 经过几天的学习与实操,对于MQTT(主要针对 v3.1.1版本)的学习告一段落,为了方便日后的查阅 本文链接:<MQTT 协议学习: 总结 与 各种定义的速查表> 章节整理 MQTT ... 
- MQTT 协议学习:004-MQTT建立通信与 CONNECT 、CONNACK 报文
		背景 上一讲 MQTT 协议学习:通信报文的构成介绍了在MQTT通信中,各报文的通信流程:从本讲开始,我们开始介绍实际中使用的报文,以及它们的组成. CONNECT - 连接请求 报文 客户端到服务端 ... 
- MQTT协议学习笔记
		1.前沿 万物联网的时代即将到来,物联网也由当初的概念开始进一步落实.随着无线网络技术飞速发展,各种设备都可以连接网络,实现远程控制.例如智能家居最近非常火爆,智能插座.智能LED灯.智能摄像头等.在 ... 
- MQTT 协议学习:000-有关概念入门
		背景 从本章开始,在没有特殊说明的情况下,文章中的MQTT版本均为 3.1.1. MQTT 协议是物联网中常见的协议之一,"轻量级物联网消息推送协议",MQTT同HTTP属于第七层 ... 
- MQTT 协议学习:002- 通信报文的构成
		背景 之前工作中参与有关协议调试的时候,发现对于协议帧的解析是比较重要的. 参考:<MQTT协议 -- 消息报文格式>.<基于STM32实现MQTT>.<MQTT协议从服 ... 
- MQTT协议学习总结
		一.MQTT介绍 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通 ... 
- MQTT协议学习研究 & Mosquitto简要教程(安装和使用)
		若初次接触MQTT协议,可先理解以下概念: [MQTT协议特点]——相比于RESTful架构的物联网系统,MQTT协议借助消息推送功能,可以更好地实现远程控制. [MQTT协议角色]——在RESTfu ... 
- MQTT协议学习及实践(Linux服务端,Android客户端的例子)
		前言 MQTT(Message Queuing Telemetry Transport),是一个物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提 ... 
- MQTT 协议学习: QoS等级 与 会话
		背景 QoS 等级 与 通信的流程有关,直接影响了整个通信.而且篇幅比较长,所以我觉得应该单独拎出来讲一下. 概念 QoS 代表了 服务质量等级. 设置上,由2 位 的二进制控制,且值不允许为 3(0 ... 
随机推荐
- IELTS Writing Task 1: two-chart answer
			Thursday, January 09, 2020 The chart below shows the value of one country's exports in various categ ... 
- EC20的低功耗模式
			EC20的支持以下几种工作模式,睡眠模式包括MCU主机睡眠和EC20睡眠. 当MCU主机不睡眠时,通过AT+QICSK =1(发送完之后串口被禁用不再响应AT指令),DTR=1(投票EC20可以进入睡 ... 
- Redis的安装配置及简单集群部署
			最近针对中铁一局项目,跟事业部讨论之后需要我们的KF平台能够接入一些开源的数据库,于是这两天研究了一下Redis的原理. 1. Redis的数据存储原理及简述 1.1Redis简述 Redis是一个基 ... 
- 利用kali自带的msfvenom工具生成远程控制软件(木马)
			2.生成一个简单的木马 3. 4. 5. 6.接下来生成的winx64muma.exe实际演示 7.将生成的winx64muma.exe在受害者机器上运行 8.在kali下输入msfconsole 9 ... 
- vbs操作IE对象
			Dim fso,filepath,i 'Dim ExcelBook,ExcelSheet,MyExcelBook,MyExcelSheet Dim ie Set ie=WScript.CreateOb ... 
- VS2017+EF6+MySQL8.0配置(.Net Framework 4.5)
			开发环境Vs2017 运行环境:.Net Framework 4.5(win7专业版 64位) 1.下载安装mysql数据库版本:mysql-8.0.19-winx64 ----数据库版本貌似跟My ... 
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表格:基本的表格
			<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ... 
- linux sed命令(擅长输出行)(转)
			linux命令总结sed命令详解 Sed 简介 sed 是一种新型的,非交互式的编辑器.它能执行与编辑器 vi 和 ex 相同的编辑任务.sed 编辑器没有提供交互式使用方式,使用者只能在命令行输入编 ... 
- swoole之内存
			一.代码 <?php // 可以用来数据共享 // 执行完后 自动释放 // 创建内存表 $table = new swoole_table(1024); // 内存表增加一列 $table-& ... 
- display:flex下子元素宽度无效
			在子元素上设置: width:60px; flex-shrink:0; 
