I wrote an asynchronous SSL socket implementation using standalone asio and am struggling to get it to reconnect after a connection reset / close by the server. I am rather new to the asio library so please bear with me.
The thread that calls io_context::run
remains blocked even after a disconnect because of the steady_timer
. My close()
logic is responsible for resetting the socket resources and is also responsible for trying to kill the timer. This is what my code looks like right now:
Creating my async job:
timer.async_wait(std::bind(&ssl_socket::heartbeat, this));
In my close()
method:
timer.expires_at(std::chrono::steady_clock::now());
timer.cancel();
According to the boost docs, cancel()
should:
Cancel any asynchronous operations that are waiting on the timer.
Perhaps I misinterpreting this but I would imagine this also cancels the asynchronous job that is bound to the io_context
but it doesn't. io_context::run
is never released and creates a deadlock.
This is what my timer handler looks like:
void ssl_socket::heartbeat() {
spdlog::get("console")->trace("heartbeat called");
if (connected_) {
write(heartbeat_token);
spdlog::get("console")->trace("heartbeat sent");
}
timer.expires_at(std::chrono::steady_clock::now() + std::chrono::seconds(heartbeat_interval));
timer.async_wait(std::bind(&ssl_socket::heartbeat, this));
}
I would like to keep handler away from having to validate if it should renew its timer and let the close()
deal with that (if possible).