mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Fix API connection sending ping too early after connection establishment (#8840)
This commit is contained in:
		| @@ -79,7 +79,11 @@ APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *pa | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
| void APIConnection::start() { | void APIConnection::start() { | ||||||
|   this->last_traffic_ = millis(); |   this->last_traffic_ = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|  |   // Set next_ping_retry_ to prevent immediate ping | ||||||
|  |   // This ensures the first ping happens after the keepalive period | ||||||
|  |   this->next_ping_retry_ = this->last_traffic_ + KEEPALIVE_TIMEOUT_MS; | ||||||
|  |  | ||||||
|   APIError err = this->helper_->init(); |   APIError err = this->helper_->init(); | ||||||
|   if (err != APIError::OK) { |   if (err != APIError::OK) { | ||||||
| @@ -163,17 +167,16 @@ void APIConnection::loop() { | |||||||
|   if (!this->initial_state_iterator_.completed() && this->list_entities_iterator_.completed()) |   if (!this->initial_state_iterator_.completed() && this->list_entities_iterator_.completed()) | ||||||
|     this->initial_state_iterator_.advance(); |     this->initial_state_iterator_.advance(); | ||||||
|  |  | ||||||
|   static uint32_t keepalive = 60000; |  | ||||||
|   static uint8_t max_ping_retries = 60; |   static uint8_t max_ping_retries = 60; | ||||||
|   static uint16_t ping_retry_interval = 1000; |   static uint16_t ping_retry_interval = 1000; | ||||||
|   const uint32_t now = App.get_loop_component_start_time(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if (this->sent_ping_) { |   if (this->sent_ping_) { | ||||||
|     // Disconnect if not responded within 2.5*keepalive |     // Disconnect if not responded within 2.5*keepalive | ||||||
|     if (now - this->last_traffic_ > (keepalive * 5) / 2) { |     if (now - this->last_traffic_ > (KEEPALIVE_TIMEOUT_MS * 5) / 2) { | ||||||
|       on_fatal_error(); |       on_fatal_error(); | ||||||
|       ESP_LOGW(TAG, "%s didn't respond to ping request in time. Disconnecting...", this->client_combined_info_.c_str()); |       ESP_LOGW(TAG, "%s didn't respond to ping request in time. Disconnecting...", this->client_combined_info_.c_str()); | ||||||
|     } |     } | ||||||
|   } else if (now - this->last_traffic_ > keepalive && now > this->next_ping_retry_) { |   } else if (now - this->last_traffic_ > KEEPALIVE_TIMEOUT_MS && now > this->next_ping_retry_) { | ||||||
|     ESP_LOGVV(TAG, "Sending keepalive PING..."); |     ESP_LOGVV(TAG, "Sending keepalive PING..."); | ||||||
|     this->sent_ping_ = this->send_ping_request(PingRequest()); |     this->sent_ping_ = this->send_ping_request(PingRequest()); | ||||||
|     if (!this->sent_ping_) { |     if (!this->sent_ping_) { | ||||||
|   | |||||||
| @@ -15,6 +15,9 @@ | |||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace api { | namespace api { | ||||||
|  |  | ||||||
|  | // Keepalive timeout in milliseconds | ||||||
|  | static constexpr uint32_t KEEPALIVE_TIMEOUT_MS = 60000; | ||||||
|  |  | ||||||
| using send_message_t = bool (APIConnection::*)(void *); | using send_message_t = bool (APIConnection::*)(void *); | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user