본문 바로가기

Rust/tauri

tauri, command 와 event 예제

[1. 개요]

tauri 에서 command 는 js 에서 rust 함수를 호출하게 할 수 있다.

반대로, rust 에서 js 함수를 직접 호출하게 할 수는 없지만(?)

js 에서 listen 중인 event 를 발생시켜, rust 에서 원하는 시점에 js 에 함수를 간접적으로 호출하게 할 수 있다.


[2. 예제]

  1. js 에서 rust 함수 호출하기
  2. app 에서 버튼 클릭 시, rust 에서 필요 시, js 로 event 발생
mkdir tauri-test
cd tauri_test
cargo tauri init
# 적절히 입력.
# 아래 그림 참조.

mkdir ui

 

이 과정을 거치면 프로젝트는 아래와 같은 구조가 된다.

tauri-test\

  • src-tauri\
  • ui\

이제 ui 폴더에 아래와 같은 파일과 각 파일에 코드를 작성한다.

// main.js
const { invoke } = window.__TAURI__.tauri; // 사용법 주의
const { emit, listen } = window.__TAURI__.event;

let count = 0;

function trigger() {
    // json 형태로, rust 함수에 인자를 전달한다.
    const result = invoke('calling_from_frontend', {from_js: "hi i am frontend", value: count});
    return result;
}

window.document.addEventListener("DOMContentLoaded", (ev) => {
    const btn_new = document.getElementById('btn_new');
    btn_new.addEventListener("click", () => {
        count++;
        const result = trigger();
        result.then((v) => btn_new.textContent = v);
    });

    const btn_new_1 = document.getElementById('btn_new_1');
    btn_new_1.addEventListener("click", () => {
        invoke('setup_event', {value: 123});
    })

    listen("backend-ping", function(event) {
        console.log("event from backend ... ", event.payload);
    })
});

<!-- index.html -->
<html>
    <head>
        <script src="main.js"></script>
    </head>

    <body>
        <button id="btn_new" style="width: 250px; height: 250px;">Click here</button>
        <button id="btn_new_1" style="width: 250px; height: 250px;">Click here 2</button>
    </body>
</html>

// main.rs

// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use tauri::{Manager, Window};
use std::thread::sleep;
use std::time::Duration;

// Rust using snake_case
// the arguments are converted to camelCase for JavaScript.
#[tauri::command(rename_all = "snake_case")]
fn calling_from_frontend(from_js : String, value: i64) -> String {
  println!("This is backend // {} // {}", from_js, value);
  format!("{} ## {}", from_js, value)
}

#[derive(Clone, serde::Serialize)]
struct Payload {
  message: String,
  value: i64,
}

#[tauri::command]
fn setup_event(value: i64, window: Window, app: tauri::AppHandle) {
  println!("{:?}", window);
  println!("value {}", value);

  let payload = Payload {
    message: "ping".to_string(),
    value: value,
  };

  // window.emit("backend-ping", payload).unwrap();
  
  // label 은 tauri.conf.json 에서
  // windows 밑에 명시하도록 한다.
  app.emit_to("mylabel", "backend-ping", payload).unwrap();
}

fn main() {
  tauri::Builder::default()
    .setup(|app| {
      let app_handle = app.app_handle();
      tauri::async_runtime::spawn(async move {
        loop {
            sleep(Duration::from_millis(2000));
            println!("sending backend-ping");
            app_handle.emit_all("backend-ping", "ping").unwrap();
        }
    });
    Ok(())
    })
    .invoke_handler(tauri::generate_handler![calling_from_frontend, setup_event])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}


마지막으로, tauri.conf.json 에서 build 항목에 다음을 추가하도록 한다.

  • "withGlobalTauri": true

windows 항목에 label 을 명시하도록 한다.


[3. ref]

'Rust > tauri' 카테고리의 다른 글

Rust, tauri 개발 환경 설정  (0) 2023.12.13