MQTT协议Keep Alive详解

为什么需要Keep Alive

MQTT协议是承载于TCP协议之上的,而TCP协议以连接为导向,在连接双方之间,提供稳定、有序的字节流功能。但是,在部分情况下,TCP可能出现半连接问题。所谓半连接,是指某一方的连接已经断开或者没有建立,而另外一方的连接却依然维持着。在这种情况下,半连接的一方可能会持续不断地向对端发送数据,而显然这些数据永远到达不了对端。为了避免半连接导致的通信黑洞,MQTT协议提供了Keep Alive机制,使客户端和 MQTT服务器可以判定当前是否存在半连接问题,从而关闭对应连接。

MQTT Keep Alive的机制流程与使用

启用Keep Alive

客户端在创建和MQTT Broker的连接时,只要将连接请求协议包内的 Keep Alive 可变头部字段设置为非0值,就可以在通信双方间启用Keep Alive机制。 Keep Alive 为0~65535的一个整数,代表客户端发送两次MQTT协议包之间的最大间隔时间。

而Broker在收到客户端的连接请求后,会检查可变头部中的 Keep Alive 字段的值,如果有值,则Broker将会启用Keep Alive机制。

MQTT 5.0 Server Keep Alive

在 MQTT 5.0 标准中,引入了 Server Keep Alive 的概念,允许Broker根据自身的实现等因素,选择接受客户端请求中携带的 Keep Alive 值,或者是覆盖这个值。如果Broker选择覆盖这个值,则需要将新值设置在连接确认包(CONNACK)的 Server Keep Alive 字段中,客户端如果在连接确认包中读取到了 Server Keep Alive,则需要使用该值,覆盖自己之前的 Keep Alive 的值。

Keep Alive机制流程

客户端流程

在连接建立后,客户端需要确保,自己任意两次MQTT协议包的发送间隔不超过 Keep Alive 的值,如果客户端当前处于空闲状态,没有可发送的包,则可以发送 PINGREQ协议包。

当客户端发送PINGREQ协议包后,Broker必须返回一个PINGRESP协议包,如果客户端在一个可靠的时间内,没有收到服务器的PINGRESP协议包,则说明当前存在半连接、或者Broker已经下线、或者出现了网络故障,这个时候,客户端应当关闭当前连接。

Broker流程

在连接建立后,Broker如果没有在 Keep Alive 的1.5倍时间内,收到来自客户端的任何包,则会认为和客户端之间的连接出现了问题,此时Broker便会断开和客户端的连接。

如果Broker收到了来自客户端的PINGREQ协议包,需要回复一个PINGRESP协议包进行确认。

客户端接管机制

当Broker里存在半连接时,如果对应的客户端发起了重连或新的连接,则Broker会启动客户端接管机制:关闭旧的半连接,然后与客户端建立新的连接。

这种机制保证了客户端不会因为Broker里存在的半连接,导致无法进行重连。

Keep Alive与遗嘱消息

Keep Alive通常还可以与遗嘱消息结合使用,通过遗嘱消息,设备可将自己的意外掉线情况及时通知第三方。

如下图,该客户端连接时设置了Keep Alive为5秒,并且设置了遗嘱消息。那么当服务器7.5秒(1.5倍Keep Alive)内未收到该客户端的任何报文时,即会向 last_will 主题发送Payload为 offline 的遗嘱消息。

如何在EMQX中使用Keep Alive

在EMQX中,用户可以通过配置来自定义Keep Alive机制的行为,主要配置字段有:

zone.${zoneName}.server_Keep Aliveserver_Keep Alive类型默认值整型无

如果没有设置这个值,则EMQX会按照客户端创建连接时的 Keep Alive 的值,来控制Keep Alive的行为。

如果设置了这个值,则Broker会对该zone下面所有的连接,强制启用Keep Alive机制,并且会使用这个值,覆盖客户端连接请求中的值。

zone.${zoneName}.Keep Alive_backoffKeep Alive_backoff类型默认值浮点数0.75

MQTT协议中要求Broker在1.5倍 Keep Alive 时间内,如果没有收到客户端的任何协议包,则认定客户端断开了连接。

而在EMQX中,我们引入了退让系数(Keep Alive back off),并将这个系数通过配置暴露出来,方便用户更灵活的控制Broker端的Keep Alive行为。

在引入退让系数后,EMQX通过下面的公式来计算最大超时时间:

Keep Alive*backoff*2

Back off 默认值为0.75,因此在用户不修改该配置的情况下,EMQX的行为完全符合MQTT标准。

Web Socket连接时设置Keep Alive

EMQX支持客户端通过Web Socket接入,当客户端使用Web Socket发起连接时,只需要在连接参数中设置上Keep Alive的值即可。

结语

本文介绍了MQTT协议中Keep Alive的机制及EMQX中Keep Alive的使用,开发者可以借助这一特性确保 MQTT连接的稳定性,构建更加健壮的上层物联网应用。读者可根据本文所学尝试上手使用MQTT应用及服务开发,探索MQTT的更多高级应用。

原文链接:,转发请注明来源!