Skip to content

Commit e951fba

Browse files
committed
feat(mqtt): 实现动态计算自动重连延迟时长功能
1 parent 06ad836 commit e951fba

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

examples/mqtt/conn/conn.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ int main(int argc, char **argv)
4242

4343
mqtt::Client::Config conf;
4444
conf.auto_reconnect_enable = true;
45-
conf.auto_reconnect_wait_sec = 5;
45+
//conf.auto_reconnect_wait_sec = 5;
46+
conf.auto_reconnect_wait_sec_gen_func = [](int fail_count) { return 1 << fail_count; };
4647
#if 0
4748
conf.base.broker.domain = "cppmain.cpp";
4849
conf.base.broker.port = 1883;

modules/mqtt/client.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ struct Client::Data {
8282
/// 在回调函数执行之前,检查一下这个 std::weak_ptr 是否过期就可以得知 this 指针是否有效。
8383
/// 进而避免继续访问到无效 this 指向的内容。
8484

85+
int connect_fail_count = 0; //!< 单次连接失败
86+
8587
static int _instance_count;
8688
};
8789

@@ -289,6 +291,7 @@ bool Client::start()
289291

290292
CHECK_DELETE_RESET_OBJ(d_->sp_thread);
291293
auto is_alive = d_->alive_tag.get(); //! 原理见Q1
294+
d_->connect_fail_count = 0;
292295

293296
//! 由于 mosquitto_connect() 是阻塞函数,为了避免阻塞其它事件,特交给子线程去做
294297
d_->sp_thread = new thread(
@@ -609,13 +612,17 @@ void Client::onTcpConnectDone(int ret)
609612
CHECK_DELETE_RESET_OBJ(d_->sp_thread);
610613

611614
if (ret == MOSQ_ERR_SUCCESS) {
615+
d_->connect_fail_count = 0;
612616
LogDbg("connect success");
613617
enableSocketRead();
614618
enableSocketWriteIfNeed();
615619
updateStateTo(State::kTcpConnected);
616620

617621
} else {
618-
LogNotice("connect fail, rc:%d, %s", ret, mosquitto_strerror(ret));
622+
++d_->connect_fail_count;
623+
LogNotice("connect fail, rc:%d, %s, fail_count:%d",
624+
ret, mosquitto_strerror(ret), d_->connect_fail_count);
625+
619626
tryReconnect();
620627

621628
++d_->cb_level;
@@ -679,17 +686,24 @@ void Client::tryReconnect()
679686
{
680687
//! 如果开启了自动重连
681688
if (d_->config.auto_reconnect_enable) {
682-
if (d_->config.auto_reconnect_wait_sec > 0) {
683-
LogDbg("reconnect after %d sec", d_->config.auto_reconnect_wait_sec);
684-
d_->reconnect_wait_remain_sec = d_->config.auto_reconnect_wait_sec;
689+
auto wait_remain_sec = d_->config.auto_reconnect_wait_sec;
690+
691+
//! 如果设置了 auto_reconnect_wait_sec_gen_func 函数
692+
//! 就则使用 auto_reconnect_wait_sec_gen_func 函数生成 wait_remain_sec
693+
if (d_->config.auto_reconnect_wait_sec_gen_func)
694+
wait_remain_sec = d_->config.auto_reconnect_wait_sec_gen_func(d_->connect_fail_count);
695+
696+
if (wait_remain_sec > 0) {
697+
LogDbg("reconnect after %d sec", wait_remain_sec);
685698
updateStateTo(State::kReconnWaiting);
686699

687700
} else {
688701
LogDbg("reconnect now");
689-
d_->reconnect_wait_remain_sec = 0;
690702
updateStateTo(State::kConnecting);
691703
}
692704

705+
d_->reconnect_wait_remain_sec = wait_remain_sec;
706+
693707
} else { //! 如果不需要自动重连
694708
LogDbg("no need reconnect, end");
695709
updateStateTo(State::kEnd);

modules/mqtt/client.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ class Client {
8787

8888
bool auto_reconnect_enable = true; //! 是否自动重连
8989
int auto_reconnect_wait_sec = 0; //! 自动重连等待时长,秒
90+
//! 根据失败次数动态生成自动重连等待时长,秒
91+
std::function<int(int)> auto_reconnect_wait_sec_gen_func;
9092

9193
bool isValid() const;
9294
};

0 commit comments

Comments
 (0)