fix(native): 修复 CDP 附着卡死问题

This commit is contained in:
leeguooooo
2026-03-09 17:10:42 +09:00
parent 5d149afef1
commit b3ed4b63be
2 changed files with 90 additions and 50 deletions
+20 -12
View File
@@ -107,11 +107,31 @@ fn main() {
let args: Vec<String> = env::args().skip(1).collect();
let mut flags = parse_flags(&args);
let clean = clean_args(&args);
let command_name = clean.first().map(|s| s.as_str());
if flags.engine.is_some() && !flags.native {
flags.native = true;
}
let can_try_default_cdp = flags.cdp.is_none()
&& !flags.auto_connect
&& flags.provider.is_none()
&& flags.executable_path.is_none()
&& flags.state.is_none()
&& flags.proxy.is_none()
&& flags.args.is_none()
&& flags.user_agent.is_none()
&& !flags.ignore_https_errors
&& !flags.allow_file_access
&& flags.extensions.is_empty();
let can_force_native_for_cdp = !matches!(command_name, Some("close"));
if !flags.native
&& can_force_native_for_cdp
&& (flags.cdp.is_some() || flags.auto_connect || can_try_default_cdp)
{
flags.native = true;
}
let has_help = args.iter().any(|a| a == "--help" || a == "-h");
let has_version = args.iter().any(|a| a == "--version" || a == "-V");
@@ -605,18 +625,6 @@ fn main() {
// Project policy: when no explicit connection mode is provided,
// commands should attach to an existing browser.
// Try CDP :9333 first, then fall back to auto-connect discovery.
let can_try_default_cdp = flags.cdp.is_none()
&& !flags.auto_connect
&& flags.provider.is_none()
&& flags.executable_path.is_none()
&& flags.state.is_none()
&& flags.proxy.is_none()
&& flags.args.is_none()
&& flags.user_agent.is_none()
&& !flags.ignore_https_errors
&& !flags.allow_file_access
&& flags.extensions.is_empty();
if can_try_default_cdp {
let mut launch_cmd = json!({
"id": gen_id(),
+70 -38
View File
@@ -2,6 +2,7 @@ use serde_json::{json, Value};
use std::collections::HashSet;
use std::sync::Arc;
use tokio::sync::Mutex;
use tokio::time::{timeout, Duration};
use super::cdp::chrome::{
auto_connect_cdp, discover_cdp_url, launch_chrome, ChromeProcess, LaunchOptions,
@@ -277,6 +278,50 @@ impl BrowserManager {
Self::connect_cdp(&ws_url).await
}
async fn create_and_attach_blank_page(&mut self) -> Result<(), String> {
let result: CreateTargetResult = self
.client
.send_command_typed(
"Target.createTarget",
&CreateTargetParams {
url: "about:blank".to_string(),
},
None,
)
.await?;
let attach_result: AttachToTargetResult = self
.client
.send_command_typed(
"Target.attachToTarget",
&AttachToTargetParams {
target_id: result.target_id.clone(),
flatten: true,
},
None,
)
.await?;
self.enable_domains_with_timeout(&attach_result.session_id)
.await?;
self.pages = vec![PageInfo {
target_id: result.target_id,
session_id: attach_result.session_id,
url: "about:blank".to_string(),
title: String::new(),
target_type: "page".to_string(),
}];
self.active_page_index = 0;
Ok(())
}
async fn enable_domains_with_timeout(&self, session_id: &str) -> Result<(), String> {
timeout(Duration::from_secs(3), self.enable_domains(session_id))
.await
.map_err(|_| format!("Timed out enabling CDP domains for session {}", session_id))?
}
async fn discover_and_attach_targets(&mut self) -> Result<(), String> {
self.client
.send_command_typed::<_, Value>(
@@ -300,40 +345,9 @@ impl BrowserManager {
.collect();
if page_targets.is_empty() {
// Create a new tab
let result: CreateTargetResult = self
.client
.send_command_typed(
"Target.createTarget",
&CreateTargetParams {
url: "about:blank".to_string(),
},
None,
)
.await?;
let attach_result: AttachToTargetResult = self
.client
.send_command_typed(
"Target.attachToTarget",
&AttachToTargetParams {
target_id: result.target_id.clone(),
flatten: true,
},
None,
)
.await?;
self.pages.push(PageInfo {
target_id: result.target_id,
session_id: attach_result.session_id.clone(),
url: "about:blank".to_string(),
title: String::new(),
target_type: "page".to_string(),
});
self.active_page_index = 0;
self.enable_domains(&attach_result.session_id).await?;
self.create_and_attach_blank_page().await?;
} else {
let mut attached_pages = Vec::new();
for target in &page_targets {
let attach_result: AttachToTargetResult = self
.client
@@ -347,18 +361,36 @@ impl BrowserManager {
)
.await?;
self.pages.push(PageInfo {
let page_info = PageInfo {
target_id: target.target_id.clone(),
session_id: attach_result.session_id.clone(),
url: target.url.clone(),
title: target.title.clone(),
target_type: target.target_type.clone(),
});
};
match self
.enable_domains_with_timeout(&attach_result.session_id)
.await
{
Ok(()) => attached_pages.push(page_info),
Err(err) => {
if std::env::var("AGENT_BROWSER_DEBUG").as_deref() == Ok("1") {
eprintln!(
"[DEBUG] Skipping CDP target '{}' ({}): {}",
target.title, target.url, err
);
}
}
}
}
self.active_page_index = 0;
let session_id = self.pages[0].session_id.clone();
self.enable_domains(&session_id).await?;
if attached_pages.is_empty() {
self.create_and_attach_blank_page().await?;
} else {
self.pages = attached_pages;
self.active_page_index = 0;
}
}
Ok(())