Skip to content

Commit

Permalink
fix(devtools): fix the invalidation of source and memory after reconn…
Browse files Browse the repository at this point in the history
…ecting for ios
  • Loading branch information
Cyunong committed Nov 20, 2024
1 parent a98db03 commit 64ad4e7
Show file tree
Hide file tree
Showing 13 changed files with 40 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace hippy::devtools {
class DevtoolsBackendService : public std::enable_shared_from_this<DevtoolsBackendService> {
public:
DevtoolsBackendService(const DevtoolsConfig& devtools_config,
std::shared_ptr<footstone::WorkerManager> worker_manager);
std::shared_ptr<footstone::WorkerManager> worker_manager, std::function<void()> reconnect_handler);

~DevtoolsBackendService();

Expand Down
3 changes: 2 additions & 1 deletion devtools/devtools-backend/include/tunnel/net_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ constexpr uint8_t kTaskFlag = 210; // message flag
class NetChannel {
public:
using ReceiveDataHandler = std::function<void(const std::string& msg, uint8_t flag)>;
using ReconnectHandler = std::function<void()>;

virtual ~NetChannel() {}

/**
* @brief connect to frontend
* @param handler to receive msg from frontend
*/
virtual void Connect(ReceiveDataHandler handler) = 0;
virtual void Connect(ReceiveDataHandler handler, ReconnectHandler reconnect_handler) = 0;

/**
* @brief send data to frontend
Expand Down
2 changes: 1 addition & 1 deletion devtools/devtools-backend/include/tunnel/tcp/tcp_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ constexpr int32_t kBufferSize = 32 * 1024;
class TcpChannel : public hippy::devtools::NetChannel, public std::enable_shared_from_this<TcpChannel> {
public:
TcpChannel();
void Connect(ReceiveDataHandler handler) override;
void Connect(ReceiveDataHandler handler, ReconnectHandler reconnect_handler) override;
void Send(const std::string& data) override;
void Close(int32_t code, const std::string& reason) override;

Expand Down
2 changes: 1 addition & 1 deletion devtools/devtools-backend/include/tunnel/tunnel_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class TunnelService : public std::enable_shared_from_this<TunnelService> {
/**
* @brief connect to frontend
*/
void Connect();
void Connect(std::function<void()> reconnect_handler);

/**
* @brief send data to frontend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ namespace hippy::devtools {
class WebSocketChannel : public hippy::devtools::NetChannel, public std::enable_shared_from_this<WebSocketChannel> {
public:
explicit WebSocketChannel(const std::string& ws_uri);
void Connect(ReceiveDataHandler handler) override;
void Connect(ReceiveDataHandler handler, ReconnectHandler reconnect_handler) override;
void Send(const std::string& rsp_data) override;
void Close(int32_t code, const std::string& reason) override;

private:
void StartConnect(const std::string& ws_uri);
void HandleSocketInit(const websocketpp::connection_hdl& handle);
void HandleSocketConnectFail(const websocketpp::connection_hdl& handle);
void HandleSocketConnectOpen(const websocketpp::connection_hdl& handle);
void HandleSocketConnectOpen(const websocketpp::connection_hdl& handle, ReconnectHandler reconnect_handler);
void HandleSocketConnectMessage(const websocketpp::connection_hdl& handle, const WSMessagePtr& message_ptr);
void HandleSocketConnectClose(const websocketpp::connection_hdl& handle);
void attempt_reconnect();
Expand Down
5 changes: 3 additions & 2 deletions devtools/devtools-backend/src/api/devtools_backend_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@

namespace hippy::devtools {
DevtoolsBackendService::DevtoolsBackendService(const DevtoolsConfig& devtools_config,
std::shared_ptr<footstone::WorkerManager> worker_manager) {
std::shared_ptr<footstone::WorkerManager> worker_manager,
std::function<void()> reconnect_handler) {
FOOTSTONE_DLOG(INFO) << kDevToolsTag << "DevtoolsBackendService create framework:" << devtools_config.framework
<< ",tunnel:" << devtools_config.tunnel;
auto data_provider = std::make_shared<DataProvider>();
Expand All @@ -38,7 +39,7 @@ DevtoolsBackendService::DevtoolsBackendService(const DevtoolsConfig& devtools_co
domain_dispatch_ = std::make_shared<DomainDispatch>(data_channel_, worker_manager);
domain_dispatch_->RegisterDefaultDomainListener();
tunnel_service_ = std::make_shared<TunnelService>(domain_dispatch_, devtools_config);
tunnel_service_->Connect();
tunnel_service_->Connect(reconnect_handler);
notification_center->runtime_notification = std::make_shared<DefaultRuntimeNotification>(tunnel_service_);

if (devtools_config.framework == Framework::kHippy) {
Expand Down
3 changes: 2 additions & 1 deletion devtools/devtools-backend/src/tunnel/tcp/tcp_channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ TcpChannel::TcpChannel() {
frame_codec_ = FrameCodec();
}

void TcpChannel::Connect(ReceiveDataHandler handler) {
void TcpChannel::Connect(ReceiveDataHandler handler, ReconnectHandler reconnect_handler) {
// TODO: reconnect in TCP if needed
frame_codec_.SetEncodeCallback([WEAK_THIS](void *data, int32_t len) {
DEFINE_AND_CHECK_SELF(TcpChannel)
if (self->client_fd_ < 0) {
Expand Down
4 changes: 2 additions & 2 deletions devtools/devtools-backend/src/tunnel/tunnel_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ TunnelService::TunnelService(std::shared_ptr<DomainDispatch> dispatch, const Dev
channel_ = NetChannel::CreateChannel(devtools_config);
}

void TunnelService::Connect() {
void TunnelService::Connect(std::function<void()> reconnect_handler) {
FOOTSTONE_DLOG(INFO) << kDevToolsTag << "TunnelService, start connect.";
channel_->Connect([WEAK_THIS](const std::string& msg, int flag) {
if (flag == kTaskFlag) {
DEFINE_AND_CHECK_SELF(TunnelService)
self->HandleReceiveData(msg);
}
});
}, reconnect_handler);
dispatch_->SetResponseHandler([WEAK_THIS](const std::string &rsp_data) {
DEFINE_AND_CHECK_SELF(TunnelService)
self->channel_->Send(rsp_data);
Expand Down
16 changes: 10 additions & 6 deletions devtools/devtools-backend/src/tunnel/ws/web_socket_channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ WebSocketChannel::WebSocketChannel(const std::string& ws_uri) {
ws_client_.start_perpetual();
}

void WebSocketChannel::Connect(ReceiveDataHandler handler) {
void WebSocketChannel::Connect(ReceiveDataHandler handler, ReconnectHandler reconnect_handler) {
if (ws_uri_.empty()) {
FOOTSTONE_DLOG(ERROR) << kDevToolsTag << "websocket uri is empty, connect error";
return;
Expand All @@ -57,9 +57,9 @@ void WebSocketChannel::Connect(ReceiveDataHandler handler) {
DEFINE_AND_CHECK_SELF(WebSocketChannel)
self->HandleSocketInit(handle);
});
ws_client_.set_open_handler([WEAK_THIS](const websocketpp::connection_hdl& handle) {
ws_client_.set_open_handler([WEAK_THIS, reconnect_handler](const websocketpp::connection_hdl& handle) {
DEFINE_AND_CHECK_SELF(WebSocketChannel)
self->HandleSocketConnectOpen(handle);
self->HandleSocketConnectOpen(handle, reconnect_handler);
});
ws_client_.set_close_handler([WEAK_THIS](const websocketpp::connection_hdl& handle) {
DEFINE_AND_CHECK_SELF(WebSocketChannel)
Expand Down Expand Up @@ -131,8 +131,8 @@ void WebSocketChannel::HandleSocketConnectFail(const websocketpp::connection_hdl
<< ", remote close reason:" << con->get_remote_close_reason().c_str();
}

void WebSocketChannel::HandleSocketConnectOpen(const websocketpp::connection_hdl& handle) {
ws_reconnect_attempts = 0;
void WebSocketChannel::HandleSocketConnectOpen(const websocketpp::connection_hdl& handle,
ReconnectHandler reconnect_handler) {
connection_hdl_ = handle.lock();
FOOTSTONE_DLOG(INFO) << kDevToolsTag << "websocket connect open";
if (!connection_hdl_.lock() || unset_messages_.empty()) {
Expand All @@ -143,6 +143,10 @@ void WebSocketChannel::HandleSocketConnectOpen(const websocketpp::connection_hdl
ws_client_.send(connection_hdl_, message, websocketpp::frame::opcode::text, error_code);
}
unset_messages_.clear();
if (0 < ws_reconnect_attempts && ws_reconnect_attempts < MAX_RECONNECT_ATTEMPTS) {
reconnect_handler();
}
ws_reconnect_attempts = 0;
}

void WebSocketChannel::HandleSocketConnectMessage(const websocketpp::connection_hdl& handle,
Expand Down Expand Up @@ -174,8 +178,8 @@ void WebSocketChannel::HandleSocketConnectClose(const websocketpp::connection_hd
}

void WebSocketChannel::attempt_reconnect() {
ws_reconnect_attempts++;
if (ws_reconnect_attempts < MAX_RECONNECT_ATTEMPTS) {
ws_reconnect_attempts++;
FOOTSTONE_DLOG(INFO) << "Attempting to reconnect (" << ws_reconnect_attempts << "/"
<< MAX_RECONNECT_ATTEMPTS << ")...";
StartConnect(ws_uri_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ jint OnCreateDevtools(JNIEnv* j_env,
const string_view ws_url = JniUtils::ToStrView(j_env, j_ws_url);
DevtoolsDataSource::SetFileCacheDir(StringViewUtils::ToStdString(
StringViewUtils::ConvertEncoding(data_dir, string_view::Encoding::Utf8).utf8_value()));
auto devtools_data_source = std::make_shared<hippy::devtools::DevtoolsDataSource>(
auto devtools_data_source = std::make_shared<hippy::devtools::DevtoolsDataSource>();
devtools_data_source->create_devtools_service(
StringViewUtils::ToStdString(StringViewUtils::ConvertEncoding(ws_url, string_view::Encoding::Utf8).utf8_value()),
worker_manager);
uint32_t id = devtools::DevtoolsDataSource::Insert(devtools_data_source);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,14 @@ namespace hippy::devtools {
*/
class DevtoolsDataSource : public std::enable_shared_from_this<hippy::devtools::DevtoolsDataSource> {
public:
DevtoolsDataSource() = default;
~DevtoolsDataSource() = default;
/**
* create devtools data source instance
* create devtools service
* @param ws_url websocket url, if empty then use other tunnel
* @param worker_manager worker thread for devtools
*/
DevtoolsDataSource(const std::string& ws_url, std::shared_ptr<footstone::WorkerManager> worker_manager);
~DevtoolsDataSource() = default;
void create_devtools_service(const std::string& ws_url, std::shared_ptr<footstone::WorkerManager> worker_manager);
/**
* @brief bind dom, so that devtools can access and collect data
*/
Expand Down Expand Up @@ -110,5 +111,6 @@ class DevtoolsDataSource : public std::enable_shared_from_this<hippy::devtools::
std::shared_ptr<HippyDomData> hippy_dom_;
uint64_t listener_id_{};
std::shared_ptr<hippy::devtools::DevtoolsBackendService> devtools_service_;
std::string context_name_;
};
} // namespace hippy::devtools
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ using StringViewUtils = footstone::stringview::StringViewUtils;
static std::atomic<uint32_t> global_devtools_data_key{1};
footstone::utils::PersistentObjectMap<uint32_t, std::shared_ptr<DevtoolsDataSource>> devtools_data_map;

DevtoolsDataSource::DevtoolsDataSource(const std::string& ws_url,
void DevtoolsDataSource::create_devtools_service(const std::string& ws_url,
std::shared_ptr<footstone::WorkerManager> worker_manager) {
hippy::devtools::DevtoolsConfig devtools_config;
devtools_config.framework = hippy::devtools::Framework::kHippy;
Expand All @@ -53,7 +53,11 @@ DevtoolsDataSource::DevtoolsDataSource(const std::string& ws_url,
} else { // empty websocket url, then use tcp tunnel by usb channel
devtools_config.tunnel = hippy::devtools::Tunnel::kTcp;
}
devtools_service_ = std::make_shared<hippy::devtools::DevtoolsBackendService>(devtools_config, worker_manager);
auto reconnect_handler = [WEAK_THIS] {
DEFINE_AND_CHECK_SELF(DevtoolsDataSource)
self->SetContextName(self->context_name_);
};
devtools_service_ = std::make_shared<hippy::devtools::DevtoolsBackendService>(devtools_config, worker_manager, reconnect_handler);
devtools_service_->Create();
hippy_dom_ = std::make_shared<HippyDomData>();
}
Expand All @@ -78,6 +82,7 @@ void DevtoolsDataSource::Destroy(bool is_reload) {
}

void DevtoolsDataSource::SetContextName(const std::string& context_name) {
context_name_ = context_name;
GetNotificationCenter()->runtime_notification->UpdateContextName(context_name);
}

Expand Down
3 changes: 2 additions & 1 deletion framework/ios/base/executors/HippyJSExecutor.mm
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ - (void)setup {
NSString *wsURL = [self completeWSURLWithBridge:bridge];
if (wsURL.length > 0) {
auto workerManager = std::make_shared<footstone::WorkerManager>(1);
auto devtools_data_source = std::make_shared<hippy::devtools::DevtoolsDataSource>([wsURL UTF8String], workerManager);
auto devtools_data_source = std::make_shared<hippy::devtools::DevtoolsDataSource>();
devtools_data_source->create_devtools_service([wsURL UTF8String], workerManager);
self.pScope->SetDevtoolsDataSource(devtools_data_source);
}
}
Expand Down

0 comments on commit 64ad4e7

Please sign in to comment.