diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 92743fc4..765e556c 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3637,10 +3637,15 @@ void Td::on_alarm_timeout_callback(void *td_ptr, int64 alarm_id) { } void Td::on_alarm_timeout(int64 alarm_id) { - if (alarm_id == 0) { + if (alarm_id == ONLINE_ALARM_ID) { on_online_updated(false, true); return; } + if (alarm_id == PING_SERVER_ALARM_ID && updates_manager_ != nullptr) { + updates_manager_->ping_server(); + alarm_timeout_.set_timeout_in(PING_SERVER_ALARM_ID, PING_SERVER_TIMEOUT + Random::fast(0, PING_SERVER_TIMEOUT / 5)); + return; + } auto it = pending_alarms_.find(alarm_id); CHECK(it != pending_alarms_.end()); uint64 request_id = it->second; @@ -3657,9 +3662,9 @@ void Td::on_online_updated(bool force, bool send_update) { create_handler()->send(!is_online_); } if (is_online_) { - alarm_timeout_.set_timeout_in(0, ONLINE_TIMEOUT); + alarm_timeout_.set_timeout_in(ONLINE_ALARM_ID, ONLINE_TIMEOUT); } else { - alarm_timeout_.cancel_timeout(0); + alarm_timeout_.cancel_timeout(ONLINE_ALARM_ID); } } @@ -3822,6 +3827,10 @@ void Td::on_result(NetQueryPtr query) { updates_manager_->schedule_get_difference("failed to fetch update"); } else { updates_manager_->on_get_updates(std::move(ptr)); + if (auth_manager_->is_bot()) { + alarm_timeout_.set_timeout_in(PING_SERVER_ALARM_ID, + PING_SERVER_TIMEOUT + Random::fast(0, PING_SERVER_TIMEOUT / 5)); + } } return; } @@ -4077,8 +4086,9 @@ void Td::clear() { } if (is_online_) { is_online_ = false; - alarm_timeout_.cancel_timeout(0); + alarm_timeout_.cancel_timeout(ONLINE_ALARM_ID); } + alarm_timeout_.cancel_timeout(PING_SERVER_ALARM_ID); LOG(DEBUG) << "Requests was answered " << timer; // close all pure actors @@ -4416,7 +4426,11 @@ void Td::send_update(tl_object_ptr &&object) { } void Td::send_result(uint64 id, tl_object_ptr object) { - LOG_IF(ERROR, id == 0) << "Sending " << to_string(object) << " through send_result"; + if (id == 0) { + LOG(ERROR) << "Sending " << to_string(object) << " through send_result"; + return; + } + auto it = request_set_.find(id); if (it != request_set_.end()) { request_set_.erase(it); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index bb3c9e78..7985c3a6 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -193,7 +193,10 @@ class Td final : public NetQueryCallback { private: static constexpr const char *tdlib_version = "1.1.2"; + static constexpr int64 ONLINE_ALARM_ID = 0; static constexpr int32 ONLINE_TIMEOUT = 240; + static constexpr int64 PING_SERVER_ALARM_ID = -1; + static constexpr int32 PING_SERVER_TIMEOUT = 300; void send_result(uint64 id, tl_object_ptr object); void send_error(uint64 id, Status error); diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index de6cf1d0..1bc943a8 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -92,6 +92,29 @@ class GetUpdatesStateQuery : public Td::ResultHandler { } }; +class PingServerQuery : public Td::ResultHandler { + public: + void send() { + send_query(G()->net_query_creator().create(create_storer(telegram_api::updates_getState()))); + } + + void on_result(uint64 id, BufferSlice packet) override { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto state = result_ptr.move_as_ok(); + CHECK(state->get_id() == telegram_api::updates_state::ID); + td->updates_manager_->on_server_pong(std::move(state)); + } + + void on_error(uint64 id, Status status) override { + status.ignore(); + td->updates_manager_->on_server_pong(nullptr); + } +}; + class GetDifferenceQuery : public Td::ResultHandler { public: void send() { @@ -841,6 +864,17 @@ void UpdatesManager::init_state() { get_difference("init_state"); } +void UpdatesManager::ping_server() { + td_->create_handler()->send(); +} + +void UpdatesManager::on_server_pong(tl_object_ptr &&state) { + LOG(INFO) << "Receive " << oneline(to_string(state)); + if (state == nullptr || state->pts_ > get_pts() || state->seq_ > seq_) { + get_difference("on server pong"); + } +} + void UpdatesManager::process_get_difference_updates( vector> &&new_messages, vector> &&new_encrypted_messages, int32 qts, diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index d4dd0218..699da903 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -42,6 +42,10 @@ class UpdatesManager : public Actor { void init_state(); + void ping_server(); + + void on_server_pong(tl_object_ptr &&state); + int32 get_pts() const { return pts_manager_.mem_pts(); }