inspect (#736)
* inspect * fixes * improvements * fixes * fixes * improvements * fix null cdp url * fix rust reader loop * improvements * improvements * fixes
This commit is contained in:
@@ -12,6 +12,14 @@ use super::types::{CdpCommand, CdpEvent, CdpMessage};
|
||||
|
||||
type PendingMap = Arc<Mutex<HashMap<u64, oneshot::Sender<CdpMessage>>>>;
|
||||
|
||||
/// Raw incoming CDP message (text) broadcast to all subscribers.
|
||||
/// Used by the inspect proxy to forward responses and events to DevTools.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RawCdpMessage {
|
||||
pub text: String,
|
||||
pub session_id: Option<String>,
|
||||
}
|
||||
|
||||
pub struct CdpClient {
|
||||
ws_tx: Arc<
|
||||
Mutex<
|
||||
@@ -26,6 +34,7 @@ pub struct CdpClient {
|
||||
next_id: AtomicU64,
|
||||
pending: PendingMap,
|
||||
event_tx: broadcast::Sender<CdpEvent>,
|
||||
raw_tx: broadcast::Sender<RawCdpMessage>,
|
||||
_reader_handle: tokio::task::JoinHandle<()>,
|
||||
}
|
||||
|
||||
@@ -40,9 +49,11 @@ impl CdpClient {
|
||||
|
||||
let pending: PendingMap = Arc::new(Mutex::new(HashMap::new()));
|
||||
let (event_tx, _) = broadcast::channel(256);
|
||||
let (raw_tx, _) = broadcast::channel(512);
|
||||
|
||||
let pending_clone = pending.clone();
|
||||
let event_tx_clone = event_tx.clone();
|
||||
let raw_tx_clone = raw_tx.clone();
|
||||
|
||||
let reader_handle = tokio::spawn(async move {
|
||||
while let Some(msg) = ws_rx.next().await {
|
||||
@@ -53,8 +64,22 @@ impl CdpClient {
|
||||
Err(_) => break,
|
||||
};
|
||||
|
||||
// Broadcast raw message for inspect proxy subscribers before typed parse,
|
||||
// so messages with negative IDs (used by the inspect proxy) are still delivered.
|
||||
if raw_tx_clone.receiver_count() > 0 {
|
||||
let session_id = serde_json::from_str::<serde_json::Value>(&msg)
|
||||
.ok()
|
||||
.and_then(|v| v.get("sessionId")?.as_str().map(String::from));
|
||||
let _ = raw_tx_clone.send(RawCdpMessage {
|
||||
text: msg.clone(),
|
||||
session_id,
|
||||
});
|
||||
}
|
||||
|
||||
let parsed: CdpMessage = match serde_json::from_str(&msg) {
|
||||
Ok(m) => m,
|
||||
// Expected for inspect proxy messages with negative IDs
|
||||
// (CdpMessage.id is u64); handled via raw broadcast above.
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
@@ -81,6 +106,7 @@ impl CdpClient {
|
||||
next_id: AtomicU64::new(1),
|
||||
pending,
|
||||
event_tx,
|
||||
raw_tx,
|
||||
_reader_handle: reader_handle,
|
||||
})
|
||||
}
|
||||
@@ -138,6 +164,21 @@ impl CdpClient {
|
||||
self.event_tx.subscribe()
|
||||
}
|
||||
|
||||
/// Subscribe to all raw incoming CDP messages (responses + events).
|
||||
/// Used by the inspect proxy to forward traffic to the DevTools frontend.
|
||||
pub fn subscribe_raw(&self) -> broadcast::Receiver<RawCdpMessage> {
|
||||
self.raw_tx.subscribe()
|
||||
}
|
||||
|
||||
/// Create a lightweight handle for the inspect WebSocket proxy.
|
||||
/// Contains only what's needed to forward messages bidirectionally.
|
||||
pub fn inspect_handle(&self) -> InspectProxyHandle {
|
||||
InspectProxyHandle {
|
||||
ws_tx: self.ws_tx.clone(),
|
||||
raw_tx: self.raw_tx.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_command_typed<P: serde::Serialize, R: serde::de::DeserializeOwned>(
|
||||
&self,
|
||||
method: &str,
|
||||
@@ -160,4 +201,46 @@ impl CdpClient {
|
||||
) -> Result<Value, String> {
|
||||
self.send_command(method, None, session_id).await
|
||||
}
|
||||
|
||||
/// Send raw JSON through the WebSocket without tracking a response.
|
||||
/// Used by the inspect proxy to forward DevTools frontend messages.
|
||||
pub async fn send_raw(&self, json: String) -> Result<(), String> {
|
||||
let mut ws_tx = self.ws_tx.lock().await;
|
||||
ws_tx
|
||||
.send(Message::Text(json))
|
||||
.await
|
||||
.map_err(|e| format!("Failed to send raw CDP message: {}", e))
|
||||
}
|
||||
}
|
||||
|
||||
type WsTx = Arc<
|
||||
Mutex<
|
||||
futures_util::stream::SplitSink<
|
||||
tokio_tungstenite::WebSocketStream<
|
||||
tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>,
|
||||
>,
|
||||
Message,
|
||||
>,
|
||||
>,
|
||||
>;
|
||||
|
||||
/// Lightweight handle for the inspect WebSocket proxy, holding only
|
||||
/// the cloneable parts of CdpClient needed for bidirectional message forwarding.
|
||||
pub struct InspectProxyHandle {
|
||||
ws_tx: WsTx,
|
||||
raw_tx: broadcast::Sender<RawCdpMessage>,
|
||||
}
|
||||
|
||||
impl InspectProxyHandle {
|
||||
pub async fn send_raw(&self, json: String) -> Result<(), String> {
|
||||
let mut ws_tx = self.ws_tx.lock().await;
|
||||
ws_tx
|
||||
.send(Message::Text(json))
|
||||
.await
|
||||
.map_err(|e| format!("Failed to send raw CDP message: {}", e))
|
||||
}
|
||||
|
||||
pub fn subscribe_raw(&self) -> broadcast::Receiver<RawCdpMessage> {
|
||||
self.raw_tx.subscribe()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user