#[Vanilla JS] backend-frontend communication

7 messages · Page 1 of 1 (latest)

pseudo grotto
#

How do I send data from rust (main.rs) to the front-end using vanilla js?

I'm using a rust ping library that can work across different operating systems.
https://github.com/orf/gping/blob/master/pinger/src/lib.rs#L7-L17
I've used create-tauri-app on Windows (npm create tauri-app@latest)

✔ Project name · tauri-app
✔ Choose your package manager · npm
✔ Choose your UI template · vanilla

This is how my main function looks like (for now). I'm able to ping while GUI app is displaying and not hanging:

fn main() {
    tauri::Builder::default()
        .setup(|_app| {
            thread::spawn(move || {
                let stream = ping("google.com".to_string(), None).expect("Error pinging");
                for message in stream {
                    match message {
                        PingResult::Pong(duration, _line) => {
                            // Update front-end
                            println!("ping={:#?}", duration);
                        }
                        PingResult::Timeout(_) => {
                            println!("Timeout!");
                        }
                        PingResult::Unknown(_) => (),
                        PingResult::PingExited(e, stderr) => {
                            println!("There was an error running ping: {e}\nStderr: {stderr}\n");
                            break;
                        }
                    }
                }
            });
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
stiff jungle
#

The primary feature for this are tauri events: https://tauri.app/v1/guides/features/events (for vanillajs you need to enable withGlobalTauri in tauri.conf.json and use window.__TAURI__.event.listen instead of the shown npm imports)

#

Alternatively window.eval() (in rust) could work too if whatever you want to call in js is global, like a function on the window object

pseudo grotto
#

I have already tried using app.emit_all("cur-ping", Payload { pingmessage: "Tauri is awesome!".into() }).unwrap(); in rust
which returns the following error:

error[E0277]: `*mut ()` cannot be sent between threads safely
   --> src\main.rs:121:27
    |
121 |               thread::spawn(move || {
    |               ------------- ^------
    |               |             |
    |  _____________|_____________within this `[closure@src\main.rs:121:27: 121:34]`
    | |             |
    | |             required by a bound introduced by this call
122 | |                 let stream = ping("google.com".to_string(), None).expect("Error pinging");
123 | |                 for message in stream {
124 | |                     match message {
...   |
138 | |                 }
139 | |             });
    | |_____________^ `*mut ()` cannot be sent between threads safely
    |
    = help: within `[closure@src\main.rs:121:27: 121:34]`, the trait `Send` is not implemented for `*mut ()`
    = note: required because it appears within the type `PhantomData<*mut ()>`
    = note: required because it appears within the type `tao::event_loop::EventLoop<tauri_runtime_wry::Message<EventLoopMessage>>`
    = note: required because it appears within the type `tauri_runtime_wry::Wry<EventLoopMessage>`
    = note: required because it appears within the type `std::option::Option<tauri_runtime_wry::Wry<EventLoopMessage>>`
    = note: required because it appears within the type `tauri::App`
    = note: required because it appears within the type `&mut tauri::App`
note: required because it's used within this closure
   --> src\main.rs:121:27
    |
121 |             thread::spawn(move || {
    |                           ^^^^^^^
note: required by a bound in `std::thread::spawn`
stiff jungle
#

if you replace the app with an instance of AppHandle which you can get outside of the thread with app.handle() it should work

pseudo grotto
#

It's sort of working. In JS i'm using await listen('cur-ping', (event) => {event.payload.pingmessage}); that is returning async()=>ie(n,r)

stiff jungle
#

listen returns a function which you can use to unlisten to the event. the event really stays inside the event handler, so {event.payload.pingmessage} does nothing