feat(callback_host): close helper page on Drop via browser WS
🤖 Generated with [Qoder][https://qoder.com]
This commit is contained in:
@@ -324,6 +324,13 @@ impl BrowserCallbackExecutor for LiveBrowserCallbackHost {
|
||||
|
||||
impl Drop for LiveBrowserCallbackHost {
|
||||
fn drop(&mut self) {
|
||||
// Best-effort: tell the browser to close the helper page tab.
|
||||
close_helper_page(
|
||||
&self.browser_ws_url,
|
||||
self.host.helper_url(),
|
||||
self.use_hidden_domain,
|
||||
);
|
||||
|
||||
self.shutdown.store(true, Ordering::Relaxed);
|
||||
if let Some(handle) = self.server_thread.lock().unwrap().take() {
|
||||
let _ = handle.join();
|
||||
@@ -373,6 +380,46 @@ fn bootstrap_helper_page(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Best-effort attempt to close the helper page tab via browser WebSocket.
|
||||
/// Silently ignores all errors — this runs during Drop and must not panic.
|
||||
fn close_helper_page(browser_ws_url: &str, helper_url: &str, use_hidden_domain: bool) {
|
||||
let close_action = if use_hidden_domain {
|
||||
"sgHideBrowerserClosePage"
|
||||
} else {
|
||||
"sgBrowserClosePage"
|
||||
};
|
||||
|
||||
let result: Result<(), Box<dyn std::error::Error>> = (|| {
|
||||
// Use a raw TcpStream with timeouts instead of tungstenite::connect
|
||||
// which does not expose a connection timeout.
|
||||
let addr = browser_ws_url
|
||||
.trim_start_matches("ws://")
|
||||
.trim_start_matches("wss://");
|
||||
let stream = TcpStream::connect_timeout(
|
||||
&addr.parse().map_err(|e| format!("addr parse: {e}"))?,
|
||||
Duration::from_millis(100),
|
||||
)?;
|
||||
stream.set_read_timeout(Some(Duration::from_millis(200)))?;
|
||||
stream.set_write_timeout(Some(Duration::from_millis(200)))?;
|
||||
let (mut websocket, _) = tungstenite::client(
|
||||
browser_ws_url,
|
||||
stream,
|
||||
)?;
|
||||
websocket.send(Message::Text(
|
||||
r#"{"type":"register","role":"web"}"#.to_string().into(),
|
||||
))?;
|
||||
// Drain the welcome prelude (best-effort, ignore timeout).
|
||||
let _ = websocket.read();
|
||||
let payload = json!([helper_url, close_action, helper_url]).to_string();
|
||||
websocket.send(Message::Text(payload.into()))?;
|
||||
Ok(())
|
||||
})();
|
||||
|
||||
if let Err(err) = result {
|
||||
eprintln!("close_helper_page best-effort failed (harmless): {err}");
|
||||
}
|
||||
}
|
||||
|
||||
fn recv_bootstrap_prelude(
|
||||
websocket: &mut tungstenite::WebSocket<tungstenite::stream::MaybeTlsStream<TcpStream>>,
|
||||
) -> Result<(), PipeError> {
|
||||
|
||||
Reference in New Issue
Block a user