[fix] fix crash when signal server close the connection actively

This commit is contained in:
dijunkun
2024-09-04 17:03:09 +08:00
parent d78dc4585f
commit d285d7971a
4 changed files with 45 additions and 13 deletions

View File

@@ -29,7 +29,8 @@ enum SignalStatus {
SignalConnected, SignalConnected,
SignalFailed, SignalFailed,
SignalClosed, SignalClosed,
SignalReconnecting SignalReconnecting,
SignalServerClosed
}; };
enum TraversalMode { P2P = 0, Relay, UnknownMode }; enum TraversalMode { P2P = 0, Relay, UnknownMode };

View File

@@ -131,6 +131,10 @@ int PeerConnection::Init(PeerConnectionParams params,
ws_status_ = WsStatus::WsReconnecting; ws_status_ = WsStatus::WsReconnecting;
signal_status_ = SignalStatus::SignalReconnecting; signal_status_ = SignalStatus::SignalReconnecting;
on_signal_status_(SignalStatus::SignalReconnecting, user_data_); on_signal_status_(SignalStatus::SignalReconnecting, user_data_);
} else if (WsStatus::WsServerClosed == ws_status) {
ws_status_ = WsStatus::WsServerClosed;
signal_status_ = SignalStatus::SignalServerClosed;
on_signal_status_(SignalStatus::SignalServerClosed, user_data_);
} }
}; };

View File

@@ -23,6 +23,7 @@ WsCore::~WsCore() {
cond_var_.notify_one(); cond_var_.notify_one();
if (ping_thread_.joinable()) { if (ping_thread_.joinable()) {
ping_thread_.join(); ping_thread_.join();
heartbeat_started_ = false;
} }
m_endpoint_.stop_perpetual(); m_endpoint_.stop_perpetual();
@@ -109,13 +110,17 @@ void WsCore::Ping(websocketpp::connection_hdl hdl) {
[this] { return !running_; }); [this] { return !running_; });
} }
auto con = m_endpoint_.get_con_from_hdl(hdl); if (hdl.expired()) {
if (con && con->get_state() == websocketpp::session::state::open) { LOG_WARN("Websocket connection expired, reconnecting...");
websocketpp::lib::error_code ec; } else {
m_endpoint_.ping(hdl, "", ec); auto con = m_endpoint_.get_con_from_hdl(hdl);
if (ec) { if (con && con->get_state() == websocketpp::session::state::open) {
LOG_ERROR("Ping error: {}", ec.message()); websocketpp::lib::error_code ec;
break; m_endpoint_.ping(hdl, "", ec);
if (ec) {
LOG_ERROR("Ping error: {}", ec.message());
break;
}
} }
} }
@@ -129,7 +134,19 @@ void WsCore::OnOpen(client *c, websocketpp::connection_hdl hdl) {
ws_status_ = WsStatus::WsOpened; ws_status_ = WsStatus::WsOpened;
OnWsStatus(WsStatus::WsOpened); OnWsStatus(WsStatus::WsOpened);
ping_thread_ = std::thread(&WsCore::Ping, this, hdl); if (!heartbeat_started_) {
heartbeat_started_ = true;
running_ = true;
ping_thread_ = std::thread(&WsCore::Ping, this, hdl);
} else {
running_ = false;
cond_var_.notify_one();
if (ping_thread_.joinable()) {
ping_thread_.join();
running_ = true;
ping_thread_ = std::thread(&WsCore::Ping, this, hdl);
}
}
} }
void WsCore::OnFail(client *c, websocketpp::connection_hdl hdl) { void WsCore::OnFail(client *c, websocketpp::connection_hdl hdl) {
@@ -140,9 +157,11 @@ void WsCore::OnFail(client *c, websocketpp::connection_hdl hdl) {
} }
void WsCore::OnClose(client *c, websocketpp::connection_hdl hdl) { void WsCore::OnClose(client *c, websocketpp::connection_hdl hdl) {
ws_status_ = WsStatus::WsClosed; ws_status_ = WsStatus::WsServerClosed;
if (running_) { if (running_) {
OnWsStatus(WsStatus::WsClosed); OnWsStatus(WsStatus::WsServerClosed);
// try to reconnect
Connect(uri_);
} }
} }

View File

@@ -15,7 +15,14 @@
typedef websocketpp::client<websocketpp::config::asio_client> client; typedef websocketpp::client<websocketpp::config::asio_client> client;
enum WsStatus { WsOpening = 0, WsOpened, WsFailed, WsClosed, WsReconnecting }; enum WsStatus {
WsOpening = 0,
WsOpened,
WsFailed,
WsClosed,
WsReconnecting,
WsServerClosed
};
class WsCore { class WsCore {
public: public:
@@ -59,10 +66,11 @@ class WsCore {
websocketpp::connection_hdl connection_handle_; websocketpp::connection_hdl connection_handle_;
std::thread m_thread_; std::thread m_thread_;
std::thread ping_thread_; std::thread ping_thread_;
bool running_ = true; std::atomic<bool> running_{false};
std::mutex mtx_; std::mutex mtx_;
unsigned int interval_ = 3; unsigned int interval_ = 3;
std::condition_variable cond_var_; std::condition_variable cond_var_;
bool heartbeat_started_ = false;
WsStatus ws_status_ = WsStatus::WsClosed; WsStatus ws_status_ = WsStatus::WsClosed;
int timeout_count_ = 0; int timeout_count_ = 0;