今回は、フロントエンドとバックエンドでイベントの送受信を行う。 Events | Tauri Apps の内容。
前提
- 開発環境構築は済んでいるものとする
- See: mikoto2000/tauri
- Tauri:
- tauri-cli: 1.5.14
- rust: 1.78.0
- node: v22.2.0
- 前々々回 作成した delete-default-event をベースに作業をしたので、そのディレクトリとの差分を取ってください
- ウィンドウについてはまだ知らないので、グローバルイベントのみ作ってみる
実装
以下の実装を行う。
- フロントエンドのボタン押下時に
greet
イベントを送信 - バックエンドは、
greet
イベントをリッスン - バックエンドは、
greet
イベントが発火した 2 秒後に、greet_ended
イベントを発火する - フロントエンドは、
greet_ended
イベントをリッスン - フロントエンドは、
greet_ended
イベントが発火したら、受信したメッセージを画面に表示する
フロントエンド
listen
でイベントを待ち受け、 emit
でイベントを送信する。
...(snip)
import { emit, listen } from '@tauri-apps/api/event'
...(snip)
const [greetEndedMsg, setGreetEndedMsg] = useState("");
{/* `greet_ended` イベントをリッスン */}
listen('greet_ended', (event) => {
setGreetEndedMsg(JSON.stringify(event));
})
...(snip)
<form
className="row"
onSubmit={(e) => {
e.preventDefault();
setGreetMsg(`Hello, ${name}! You've been greeted from Rust!`);
{/*ボタン押下で `greet` イベントを emit */}
emit('greet', { greet_message: name })
}}
>
<input
id="greet-input"
onChange={(e) => setName(e.currentTarget.value)}
placeholder="Enter a name..."
/>
<button type="submit">Greet</button>
</form>
<p>{greetMsg}</p>
{/* 受信した `greet_ended` イベントのメッセージを表示 */}
<p>{greetEndedMsg}</p>
...(snip)
バックエンド
フロントエンドから受け取るイベントのペイロードは、「JSON 文字列」。
フロントエンドへ送るイベントのペイロードは、「serde::Serialize
を付与した構造体」。
こちらもフロントエンドと似たような形で、
App#listen_global
でグローバルイベントを待ち受け、
AppHandle#emit_all
でイベントをグローバルに送信する。
...(snip)
use std::{thread, time::Duration};
use tauri::Manager;
// フロントエンドから受信したメッセージをデシリアライズするための構造体
#[derive(Clone, Debug, serde::Deserialize)]
struct GreetPayload {
: String,
greet_message}
// フロントエンドへ送信するメッセージをシリアライズするための構造体
#[derive(Clone, Debug, serde::Serialize)]
struct GreetEndedPayload {
: String,
greet_ended_message}
fn main() {
tauri::Builder::default()
.setup(|app| {
let app_handle = app.handle();
// イベント `greet` の listen 開始
// listen を止めたいことがある場合、
// 戻り値の id を使って `app.unlisten(id)` とする
let _id = app.listen_global("greet", move |event| {
let emit_payload_json = event.payload().unwrap();
println!("EmitPayloadJson: {:?}", emit_payload_json);
// JSON 文字列で受け取るので、構造体へデシリアライズ
let emit_payload = serde_json::from_str::<GreetPayload>(&emit_payload_json);
println!("GreetPayload: {:?}", emit_payload);
// 構造体からメッセージを抜き出す
let greet_message = emit_payload.unwrap().greet_message;
println!("GreetPayload.greet_message: {:?}", greet_message);
// 2 秒後にイベント `greet_ended` を発火
thread::sleep(Duration::from_millis(2000));
let greet_message = format!("greet end by message: {}", greet_message);
let app_handle = app_handle.clone();
.emit_all("greet_ended", GreetEndedPayload {
app_handle: greet_message
greet_ended_message}).unwrap();
});
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
以上。
0 件のコメント:
コメントを投稿