chromiumoxide
chromiumoxide copied to clipboard
add function to set listeners for browser-wide events (targetInfoChanged, targetCreated ...)
This is split from and addresses comments on an earlier pr #34. Fixes #22.
I've changed the API to be more generic like Page::event_listener<T>()
Here's what the example usage (from #34) looks like now:
use futures::StreamExt;
use std::sync::Arc;
use chromiumoxide::error::Result;
use chromiumoxide::browser::Browser;
use chromiumoxide_cdp::cdp::browser_protocol::target::{EventTargetCreated, EventTargetInfoChanged};
mod get_debug_ws_url;
//Print title of Page
async fn page_ops(page: &chromiumoxide::Page) -> Result<(), Box<dyn std::error::Error>>{
let title = page.get_title().await?;
match title {
Some(title) => {
println!("{}", title);
},
None => {},
}
Ok(())
}
#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let debug_ws_url = get_debug_ws_url::get_ws_url().await?;
let (browser, mut handler) =
Browser::connect(debug_ws_url).await?;
let handle = async_std::task::spawn(async move {
loop {
handler.next().await;
}
});
let shared: Arc<_> = Arc::new(browser);
let browser_one = shared.clone();
let browser_two = shared.clone();
//Run functions belonging to Page instances of changed targets
let mut events = browser_two.event_listener::<EventTargetInfoChanged>().await?;
async_std::task::spawn(async move {
while let Some(event) = events.next().await {
if event.target_info.r#type == "page" {
let page = browser_one.get_page(event.target_info.target_id.clone()).await;
match page {
Ok(page) => {let _ = page_ops(&page).await;},
Err(e) => {println!("{}", e)}
}
}
}
});
//Print target_id as they're created
let mut events = browser_two.event_listener::<EventTargetCreated>().await?;
async_std::task::spawn(async move {
while let Some(event) = events.next().await {
if event.target_info.r#type == "page" {
println!("{:?}", event.target_info.target_id.clone());
}
}
});
handle.await;
Ok(())
}
@bobajeff @mattsse
Any updates on this PR?
I could really use this feature. My use case is that I have multiple Chrome instances instantiated from a Ruby process and we need to do request interception on most requests on each browser. However, doing this all in Ruby causes performance issues (partially due to the GIL).
My idea is to move the request interception logic out into Rust where we can actually use multiple cores and I imagine Rust will perform significantly better on its own anyway.
So obviously trying to keep track of pages here would be a headache and it would be significantly easier if I could just set the event listeners on the browser. I tried @bobajeff's branch and it does what I need it to do.