[fix] fix crash due to accessing to invalid virtual function

This commit is contained in:
dijunkun
2024-09-10 22:32:59 +08:00
parent a8333c622b
commit bbd05bcb8d
9 changed files with 67 additions and 100 deletions

View File

@@ -233,8 +233,7 @@ int PeerConnection::Init(PeerConnectionParams params,
} }
}; };
ws_transport_ = ws_transport_ = std::make_shared<WsClient>(on_receive_ws_msg_, on_ws_status_);
std::make_shared<WsTransmission>(on_receive_ws_msg_, on_ws_status_);
uri_ = "ws://" + cfg_signal_server_ip_ + ":" + cfg_signal_server_port_; uri_ = "ws://" + cfg_signal_server_ip_ + ":" + cfg_signal_server_port_;
if (ws_transport_) { if (ws_transport_) {
ws_transport_->Connect(uri_); ws_transport_->Connect(uri_);

View File

@@ -10,7 +10,7 @@
#include "ice_transmission.h" #include "ice_transmission.h"
#include "video_decoder_factory.h" #include "video_decoder_factory.h"
#include "video_encoder_factory.h" #include "video_encoder_factory.h"
#include "ws_transmission.h" #include "ws_client.h"
#include "x.h" #include "x.h"
typedef void (*OnReceiveBuffer)(const char *, size_t, const char *, typedef void (*OnReceiveBuffer)(const char *, size_t, const char *,
@@ -140,7 +140,7 @@ class PeerConnection {
bool try_rejoin_with_turn_ = true; bool try_rejoin_with_turn_ = true;
private: private:
std::shared_ptr<WsTransmission> ws_transport_ = nullptr; std::shared_ptr<WsClient> ws_transport_ = nullptr;
std::function<void(const std::string &)> on_receive_ws_msg_ = nullptr; std::function<void(const std::string &)> on_receive_ws_msg_ = nullptr;
std::function<void(WsStatus)> on_ws_status_ = nullptr; std::function<void(WsStatus)> on_ws_status_ = nullptr;
unsigned int ws_connection_id_ = 0; unsigned int ws_connection_id_ = 0;

View File

@@ -5,7 +5,7 @@
#include "ice_agent.h" #include "ice_agent.h"
#include "log.h" #include "log.h"
#include "ws_transmission.h" #include "ws_client.h"
#include "x.h" #include "x.h"
using nlohmann::json; using nlohmann::json;

View File

@@ -14,8 +14,7 @@ using nlohmann::json;
IceTransmission::IceTransmission( IceTransmission::IceTransmission(
bool enable_turn, bool trickle_ice, bool offer_peer, bool enable_turn, bool trickle_ice, bool offer_peer,
std::string &transmission_id, std::string &user_id, std::string &transmission_id, std::string &user_id,
std::string &remote_user_id, std::string &remote_user_id, std::shared_ptr<WsClient> ice_ws_transmission,
std::shared_ptr<WsTransmission> ice_ws_transmission,
std::function<void(std::string)> on_ice_status_change) std::function<void(std::string)> on_ice_status_change)
: enable_turn_(enable_turn), : enable_turn_(enable_turn),
trickle_ice_(trickle_ice), trickle_ice_(trickle_ice),

View File

@@ -21,7 +21,7 @@
#include "rtp_packet.h" #include "rtp_packet.h"
#include "rtp_video_receiver.h" #include "rtp_video_receiver.h"
#include "rtp_video_sender.h" #include "rtp_video_sender.h"
#include "ws_transmission.h" #include "ws_client.h"
class IceTransmission { class IceTransmission {
public: public:
@@ -38,7 +38,7 @@ class IceTransmission {
IceTransmission(bool enable_turn, bool trickle_ice, bool offer_peer, IceTransmission(bool enable_turn, bool trickle_ice, bool offer_peer,
std::string &transmission_id, std::string &user_id, std::string &transmission_id, std::string &user_id,
std::string &remote_user_id, std::string &remote_user_id,
std::shared_ptr<WsTransmission> ice_ws_transmission, std::shared_ptr<WsClient> ice_ws_transmission,
std::function<void(std::string)> on_ice_status_change); std::function<void(std::string)> on_ice_status_change);
~IceTransmission(); ~IceTransmission();
@@ -124,7 +124,7 @@ class IceTransmission {
private: private:
std::unique_ptr<IceAgent> ice_agent_ = nullptr; std::unique_ptr<IceAgent> ice_agent_ = nullptr;
std::shared_ptr<WsTransmission> ice_ws_transport_ = nullptr; std::shared_ptr<WsClient> ice_ws_transport_ = nullptr;
CongestionControl *congestion_control_ = nullptr; CongestionControl *congestion_control_ = nullptr;
std::function<void(const char *, size_t, const char *, size_t)> std::function<void(const char *, size_t, const char *, size_t)>
on_receive_video_ = nullptr; on_receive_video_ = nullptr;

View File

@@ -1,4 +1,4 @@
#include "ws_core.h" #include "ws_client.h"
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
@@ -6,7 +6,9 @@
#include "log.h" #include "log.h"
WsCore::WsCore() { WsClient::WsClient(std::function<void(const std::string &)> on_receive_msg_cb,
std::function<void(WsStatus)> on_ws_status_cb)
: on_receive_msg_(on_receive_msg_cb), on_ws_status_(on_ws_status_cb) {
m_endpoint_.clear_access_channels(websocketpp::log::alevel::all); m_endpoint_.clear_access_channels(websocketpp::log::alevel::all);
m_endpoint_.clear_error_channels(websocketpp::log::elevel::all); m_endpoint_.clear_error_channels(websocketpp::log::elevel::all);
@@ -16,7 +18,7 @@ WsCore::WsCore() {
m_thread_ = std::thread(&client::run, &m_endpoint_); m_thread_ = std::thread(&client::run, &m_endpoint_);
} }
WsCore::~WsCore() { WsClient::~WsClient() {
destructed_ = true; destructed_ = true;
running_ = false; running_ = false;
@@ -33,7 +35,7 @@ WsCore::~WsCore() {
} }
} }
int WsCore::Connect(std::string const &uri) { int WsClient::Connect(std::string const &uri) {
uri_ = uri; uri_ = uri;
websocketpp::lib::error_code ec; websocketpp::lib::error_code ec;
@@ -47,51 +49,53 @@ int WsCore::Connect(std::string const &uri) {
return -1; return -1;
} }
con->set_open_handler(websocketpp::lib::bind( con->set_open_handler(
&WsCore::OnOpen, this, &m_endpoint_, websocketpp::lib::placeholders::_1)); websocketpp::lib::bind(&WsClient::OnOpen, this, &m_endpoint_,
con->set_fail_handler(websocketpp::lib::bind( websocketpp::lib::placeholders::_1));
&WsCore::OnFail, this, &m_endpoint_, websocketpp::lib::placeholders::_1)); con->set_fail_handler(
websocketpp::lib::bind(&WsClient::OnFail, this, &m_endpoint_,
websocketpp::lib::placeholders::_1));
con->set_close_handler( con->set_close_handler(
websocketpp::lib::bind(&WsCore::OnClose, this, &m_endpoint_, websocketpp::lib::bind(&WsClient::OnClose, this, &m_endpoint_,
websocketpp::lib::placeholders::_1)); websocketpp::lib::placeholders::_1));
con->set_ping_handler(websocketpp::lib::bind( con->set_ping_handler(websocketpp::lib::bind(
&WsCore::OnPing, this, websocketpp::lib::placeholders::_1, &WsClient::OnPing, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2)); websocketpp::lib::placeholders::_2));
con->set_pong_handler(websocketpp::lib::bind( con->set_pong_handler(websocketpp::lib::bind(
&WsCore::OnPong, this, websocketpp::lib::placeholders::_1, &WsClient::OnPong, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2)); websocketpp::lib::placeholders::_2));
con->set_pong_timeout(1000); con->set_pong_timeout(1000);
con->set_pong_timeout_handler(websocketpp::lib::bind( con->set_pong_timeout_handler(websocketpp::lib::bind(
&WsCore::OnPongTimeout, this, websocketpp::lib::placeholders::_1, &WsClient::OnPongTimeout, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2)); websocketpp::lib::placeholders::_2));
con->set_message_handler(websocketpp::lib::bind( con->set_message_handler(websocketpp::lib::bind(
&WsCore::OnMessage, this, websocketpp::lib::placeholders::_1, &WsClient::OnMessage, this, websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2)); websocketpp::lib::placeholders::_2));
m_endpoint_.connect(con); m_endpoint_.connect(con);
ws_status_ = WsStatus::WsOpening; ws_status_ = WsStatus::WsOpening;
OnWsStatus(WsStatus::WsOpening); on_ws_status_(WsStatus::WsOpening);
return 0; return 0;
} }
void WsCore::Close(websocketpp::close::status::value code, std::string reason) { void WsClient::Close(websocketpp::close::status::value code,
std::string reason) {
websocketpp::lib::error_code ec; websocketpp::lib::error_code ec;
running_ = false;
m_endpoint_.close(connection_handle_, code, reason, ec); m_endpoint_.close(connection_handle_, code, reason, ec);
if (ec) { if (ec) {
LOG_ERROR("Initiating close error: {}", ec.message()); LOG_ERROR("Initiating close error: {}", ec.message());
} }
OnWsStatus(WsStatus::WsClosed);
} }
void WsCore::Send(std::string message) { void WsClient::Send(std::string message) {
websocketpp::lib::error_code ec; websocketpp::lib::error_code ec;
m_endpoint_.send(connection_handle_, message, m_endpoint_.send(connection_handle_, message,
@@ -102,7 +106,7 @@ void WsCore::Send(std::string message) {
} }
} }
void WsCore::Ping(websocketpp::connection_hdl hdl) { void WsClient::Ping(websocketpp::connection_hdl hdl) {
while (running_) { while (running_) {
{ {
std::unique_lock<std::mutex> lock(mtx_); std::unique_lock<std::mutex> lock(mtx_);
@@ -110,6 +114,10 @@ void WsCore::Ping(websocketpp::connection_hdl hdl) {
[this] { return !running_; }); [this] { return !running_; });
} }
if (!running_) {
break;
}
if (hdl.expired()) { if (hdl.expired()) {
LOG_WARN("Websocket connection expired, reconnecting..."); LOG_WARN("Websocket connection expired, reconnecting...");
} else { } else {
@@ -126,52 +134,52 @@ void WsCore::Ping(websocketpp::connection_hdl hdl) {
} }
} }
WsStatus WsCore::GetStatus() { return ws_status_; } WsStatus WsClient::GetStatus() { return ws_status_; }
void WsCore::OnOpen(client *c, websocketpp::connection_hdl hdl) { void WsClient::OnOpen(client *c, websocketpp::connection_hdl hdl) {
ws_status_ = WsStatus::WsOpened; ws_status_ = WsStatus::WsOpened;
OnWsStatus(WsStatus::WsOpened); on_ws_status_(WsStatus::WsOpened);
if (!heartbeat_started_) { if (!heartbeat_started_) {
heartbeat_started_ = true; heartbeat_started_ = true;
running_ = true; running_ = true;
ping_thread_ = std::thread(&WsCore::Ping, this, hdl); ping_thread_ = std::thread(&WsClient::Ping, this, hdl);
} else { } else {
running_ = false; running_ = false;
cond_var_.notify_one(); cond_var_.notify_one();
if (ping_thread_.joinable()) { if (ping_thread_.joinable()) {
ping_thread_.join(); ping_thread_.join();
running_ = true; running_ = true;
ping_thread_ = std::thread(&WsCore::Ping, this, hdl); ping_thread_ = std::thread(&WsClient::Ping, this, hdl);
} }
} }
} }
void WsCore::OnFail(client *c, websocketpp::connection_hdl hdl) { void WsClient::OnFail(client *c, websocketpp::connection_hdl hdl) {
ws_status_ = WsStatus::WsFailed; ws_status_ = WsStatus::WsFailed;
OnWsStatus(WsStatus::WsFailed); on_ws_status_(WsStatus::WsFailed);
Connect(uri_); Connect(uri_);
} }
void WsCore::OnClose(client *c, websocketpp::connection_hdl hdl) { void WsClient::OnClose(client *c, websocketpp::connection_hdl hdl) {
ws_status_ = WsStatus::WsServerClosed; ws_status_ = WsStatus::WsServerClosed;
on_ws_status_(WsStatus::WsServerClosed);
if (running_) { if (running_) {
OnWsStatus(WsStatus::WsServerClosed);
// try to reconnect // try to reconnect
Connect(uri_); Connect(uri_);
} }
} }
bool WsCore::OnPing(websocketpp::connection_hdl hdl, std::string msg) { bool WsClient::OnPing(websocketpp::connection_hdl hdl, std::string msg) {
return true; return true;
} }
bool WsCore::OnPong(websocketpp::connection_hdl hdl, std::string msg) { bool WsClient::OnPong(websocketpp::connection_hdl hdl, std::string msg) {
return true; return true;
} }
void WsCore::OnPongTimeout(websocketpp::connection_hdl hdl, std::string msg) { void WsClient::OnPongTimeout(websocketpp::connection_hdl hdl, std::string msg) {
if (timeout_count_ < 2) { if (timeout_count_ < 2) {
timeout_count_++; timeout_count_++;
return; return;
@@ -181,10 +189,10 @@ void WsCore::OnPongTimeout(websocketpp::connection_hdl hdl, std::string msg) {
// m_endpoint_.close(hdl, websocketpp::close::status::normal, // m_endpoint_.close(hdl, websocketpp::close::status::normal,
// "OnPongTimeout"); // "OnPongTimeout");
ws_status_ = WsStatus::WsReconnecting; ws_status_ = WsStatus::WsReconnecting;
OnWsStatus(WsStatus::WsReconnecting); on_ws_status_(WsStatus::WsReconnecting);
m_endpoint_.reset(); m_endpoint_.reset();
} }
void WsCore::OnMessage(websocketpp::connection_hdl, client::message_ptr msg) { void WsClient::OnMessage(websocketpp::connection_hdl, client::message_ptr msg) {
OnReceiveMessage(msg->get_payload()); on_receive_msg_(msg->get_payload());
} }

View File

@@ -1,5 +1,11 @@
#ifndef _WS_CORE_H_ /*
#define _WS_CORE_H_ * @Author: DI JUNKUN
* @Date: 2024-09-10
* Copyright (c) 2023 by DI JUNKUN, All Rights Reserved.
*/
#ifndef _WS_CLIENT_H_
#define _WS_CLIENT_H_
#include <condition_variable> #include <condition_variable>
#include <map> #include <map>
@@ -24,12 +30,14 @@ enum WsStatus {
WsServerClosed WsServerClosed
}; };
class WsCore { class WsClient {
public: public:
WsCore(); WsClient(std::function<void(const std::string &)> on_receive_msg_cb,
std::function<void(WsStatus)> on_ws_status_cb);
virtual ~WsCore(); ~WsClient();
public:
int Connect(std::string const &uri); int Connect(std::string const &uri);
void Close(websocketpp::close::status::value code = void Close(websocketpp::close::status::value code =
@@ -57,10 +65,6 @@ class WsCore {
void OnMessage(websocketpp::connection_hdl hdl, client::message_ptr msg); void OnMessage(websocketpp::connection_hdl hdl, client::message_ptr msg);
virtual void OnReceiveMessage(const std::string &msg) = 0;
virtual void OnWsStatus(WsStatus ws_status) = 0;
private: private:
client m_endpoint_; client m_endpoint_;
websocketpp::connection_hdl connection_handle_; websocketpp::connection_hdl connection_handle_;
@@ -76,6 +80,9 @@ class WsCore {
int timeout_count_ = 0; int timeout_count_ = 0;
std::string uri_; std::string uri_;
bool destructed_ = false; bool destructed_ = false;
std::function<void(const std::string &)> on_receive_msg_ = nullptr;
std::function<void(WsStatus)> on_ws_status_ = nullptr;
}; };
#endif #endif

View File

@@ -1,24 +0,0 @@
#include "ws_transmission.h"
#include "log.h"
WsTransmission::WsTransmission(
std::function<void(const std::string &)> on_receive_msg_cb,
std::function<void(WsStatus)> on_ws_status_cb)
: on_receive_msg_(on_receive_msg_cb), on_ws_status_(on_ws_status_cb) {}
WsTransmission::~WsTransmission() {}
void WsTransmission::OnReceiveMessage(const std::string &msg) {
// LOG_INFO("Receive msg: {}", msg);
if (on_receive_msg_) {
on_receive_msg_(msg);
}
}
void WsTransmission::OnWsStatus(WsStatus ws_status) {
// LOG_INFO("Receive msg: {}", msg);
if (on_ws_status_) {
on_ws_status_(ws_status);
}
}

View File

@@ -1,22 +0,0 @@
#ifndef _WS_TRANSMISSION_H_
#define _WS_TRANSMISSION_H_
#include "ws_core.h"
class WsTransmission : public WsCore {
public:
WsTransmission(std::function<void(const std::string &)> on_receive_msg_cb,
std::function<void(WsStatus)> on_ws_status_cb);
~WsTransmission();
public:
void OnReceiveMessage(const std::string &msg);
void OnWsStatus(WsStatus ws_status);
private:
std::function<void(const std::string &)> on_receive_msg_ = nullptr;
std::function<void(WsStatus)> on_ws_status_ = nullptr;
};
#endif