MQTT 心跳机制

翻译: https://www.hivemq.com/blog/mqtt-essentials-part-10-alive-client-take-over/

 

If the client does not send a messages during the keep-alive period, it must send a PINGREQ packet to the broker to confirm that it is available and to make sure that the broker is also still available.

如果客户端在保持活动期间未发送消息,则必须向代理发送PINGREQ包,以确认它是否可用,并确保代理仍然可用。

The broker must disconnect a client that does not send a message or a PINGREQ packet in one and a half times the keep alive interval. Likewise, the client is expected to close the connection if it does not receive a response from the broker in a reasonable amount of time.

代理必须断开客户端,该客户端在保持活动间隔的1.5T 内不发送消息或PINGREQ包。同样,如果客户机在合理的时间内没有收到代理的响应,则预期它将关闭连接。

说明:自己开发的体会,MQTT是基于TCP实现的,TCP里面的连接关闭,需要等待1.5个TLS,所以在开发MQTT时设置的是1.5TLS时间间隔,1.5TLS没有收到PINGREQ,认为连接断开,可以终止MQTT连接。

Keep Alive Flow

Let’s take a closer look at the keep alive messages. The keep alive feature uses two packets:

PINGREQ

pingreq

固定报头: 报头控制类型(0xc0),报文PINGREQ没有可变报头。

有效载荷: 剩余长度等于0, 报文PINGREQ没有有效载荷。

响应:  server收到PINGREQ报文时,必须使用PINGRESP报文响应。

The PINGREQ is sent by the client and indicates to the broker that the client is still alive. If the client does not send any other type of packets (for example, a PUBLISH or SUBSCRIBE packet), the client must send a PINGREQ packet to the broker. The client can send a PINGREQ packet any time it wants to confirm that the network connection is still alive. The PINGREQ packet does not contain a payload.

PINGREQ由客户端发送,并向代理指示客户端仍然有效。如果客户机不发送任何其他类型的数据包(例如,发布或订阅数据包),则客户机必须向代理发送PINGREQ数据包。客户机可以在任何时候发送一个PINGREQ数据包来确认网络连接仍然有效。PINGREQ数据包不包含有效负载。

 

PINGRESP

pingresp

server发送给client的PINGRESP,用于确认它还活着。保持连接(Keep Alive)处理中用到这个报文。

固定报头: 报文PINGRESP没有可变报头。

有效载荷: 报文PINGRESP没有有效载荷。

When the broker receives a PINGREQ packet, the broker must reply with a PINGRESP packet to show the client that it is still available. The PINGRESP packet also does not contain a payload.

当代理收到PINGREQ包时,代理必须用PINGRESP包进行应答,以向客户机显示它仍然可用。PINGRESP包也不包含有效负载。

Good to Know

  • If the broker does not receive a PINGREQ or any other packet from a client, the broker closes the connection and sends the last will and testament message (if the client specified an LWT).   如果代理没有从客户端接收到PINGREQ或任何其他数据包,那么代理将关闭连接并发送最后一条will和testament消息(如果客户端指定了LWT)。
  • It is the responsibility of the MQTT client to set an appropriate keep alive value. For example, the client can adjust the keep-alive interval to its current signal strength.     MQTT客户机负责设置适当的keep-alive值。例如,客户机可以将keep alive间隔调整为其当前信号强度。
  • The maximum keep alive is 18h 12min 15 sec.      最大存活时间为18小时12分15秒。
  • If the keep alive interval is 0, the keep alive mechanism is deactivated.      如果保持活动间隔为0,则停用保持活动机制。
在C++中使用MQTT时,心跳包(Pingreq/Pingresp)通常是由MQTT客户端库自动管理的,用户不需要手动发送心跳包。心跳包是用来维持客户端和服务端之间连接的一种机制,如果在一定时间内客户端和服务端没有数据交互,服务端可能会关闭这个连接。 如果你是在使用某个特定的MQTT客户端库,比如`mosquitto`、`Paho MQTT`等,那么你只需要按照该库的API设置好心跳间隔时间(keepalive interval),库会在后台自动处理心跳机制。 以`Paho MQTT`为例,你可以在创建MQTT客户端实例时设置心跳间隔时间: ```cpp #include "mqtt/client.h" int main(int argc, char* argv[]) { // 设置心跳间隔为60秒 const int keepalive_interval = 60; mqtt::client client("tcp://broker.hivemq.com:1883", "client_id", keepalive_interval); // ... 其他代码 ... return 0; } ``` 如果你确实需要手动发送心跳包,通常会使用`pingreq()`方法。但是请注意,频繁地手动发送心跳包可能会干扰正常的网络活动,因此在大多数情况下不推荐这样做。 下面是一个使用Paho C++客户端库手动发送心跳包的简单示例: ```cpp #include "mqtt/client.h" void on_failure(const mqtt::token& tok) { // 处理错误 } void on_success(const mqtt::token& tok) { // 成功发送心跳包 } int main(int argc, char* argv[]) { mqtt::client client("tcp://broker.hivemq.com:1883", "client_id"); // 连接到MQTT服务器 client.connect()->wait(); // 订阅主题,这里只是为了演示 client.subscribe("your/topic", 1)->wait(); // 发送心跳包 client.pingreq()->wait(on_failure, on_success); // ... 其他代码 ... return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值