Vanilla.js のプロジェクトを作って、「メインプロセス -> レンダープロセス」の通信を実装するところまで。
この通信のために、イベントという仕組みを利用するため、ついでに「レンダープロセス -> レンダープロセス」のイベント通信も試す。
今回は、プロジェクト作成直後から、必要な修正差分を示す形で進める。
前提
- OS: Windows 11 Pro 21H2 ビルド 22000.556
- Tauri の開発環境構が築済みであること
- Vanilla.js の Tauri プロジェクトひな形が作成済みであること
- 今回は、
tauri-app-event
という名前でプロジェクトを作成した
- 今回は、
その他、Tauri シリーズを読んでおくとよいかも。
- Docker の node コンテナで Tauri アプリに入門する - mikoto2000 の日記
- Tauri アプリ入門 2 - レンダープロセスからメインプロセスへ通信 - mikoto2000 の日記
メインプロセスからレンダープロセスへイベントを送信する
Tauri でメインプロセスからレンダープロセスへの通信を行い際には、イベントという仕組みを利用する。
今回は、以下順番で実装していく。
- Vanilla.js のための設定
- メインプロセス側にイベントを送信する関数を定義
- イベント送信処理起動コマンドの実装
- コマンドの登録
Vanilla.js のための設定
tauri.conf.json
に "withGlobalTauri": true
を追加する。
diff --git a/tauri/tauri-app-event/src-tauri/tauri.conf.json b/tauri/tauri-app-event/src-tauri/tauri.conf.json
index e5699f4..8f75c29 100644--- a/tauri/tauri-app-event/src-tauri/tauri.conf.json
+++ b/tauri/tauri-app-event/src-tauri/tauri.conf.json
@@ -7,7 +7,8 @@
"distDir": "../dist",
"devPath": "../dist",
"beforeDevCommand": "",- "beforeBuildCommand": ""
+ "beforeBuildCommand": "",
+ "withGlobalTauri": true
},
"tauri": { "bundle": {
メインプロセス側にイベントを送信する関数を定義
イベント送信処理起動コマンドの実装
Rust 側で、 AppHandle#emit_all
を実行することで、レンダープロセス側にイベントを通知できる。
第一引数にイベント名、第二引数に送信するデータを格納する。
以下では backendHello
という名前で、構造体
BackendHelloEventPayload
の構造をしたデータを送信している。
レンダープロセスで、イベントを listen する際に、イベント名を指定することで、同名のイベントを受け取れる。
diff --git a/tauri/tauri-app-event/src-tauri/src/command.rs b/tauri/tauri-app-event/src-tauri/src/command.rs
new file mode 100644
index 0000000..f1983a7--- /dev/null
+++ b/tauri/tauri-app-event/src-tauri/src/command.rs
@@ -0,0 +1,42 @@
+use std::sync::mpsc::{self, TryRecvError};
+use std::thread;
+use std::time::Duration;
+
+use tauri;
+use tauri::Manager;
+
+// レンダープロセスへ送信するデータの構造を定義した構造体
+#[derive(Clone, serde::Serialize, serde::Deserialize)]
+pub struct BackendHelloEventPayload {
+ pub message: String,
+}
+
+// 初期化用関数
+// JS のイベントリスナー `DOMContentLoaded` から、初期化時に呼び出されることを想定
+#[tauri::command]
+pub fn post_setup_process_for_backend(app: tauri::AppHandle) {
+
+ let (tx, rx) = mpsc::channel();
+
+ // 新しいスレッドを作成して、 1 秒ごとにイベントを emit する処理を実装
+ tauri::async_runtime::spawn( async move {
+ loop {
+ println!("send backendHello event.");
+ thread::sleep(Duration::from_millis(1000));
+
+ // レンダープロセスへイベント送信
+ // イベント名: backendHello
+ // 送信データ: { message: "Hello, World from backend!!!" }
+ app.emit_all("backendHello", BackendHelloEventPayload { message: "Hello, World from backend!!!".into() }).unwrap();
+
+ // emit 終了通知用チャンネルに通知が来たらループをストップ
+ match rx.try_recv() {
+ Ok(_) | Err(TryRecvError::Disconnected) => {
+ println!("stop backendHello event.");
+ break;
+ }
+ Err(TryRecvError::Empty) => {}
+ }
+ }
+ });
+
+ // 10 秒後に emit を終了(emit 終了通知用チャンネル経由でストップを通知)
+ tauri::async_runtime::spawn( async move {
+ thread::sleep(Duration::from_millis(10000));
+ let _ = tx.send(());
+ });
+}
+
コマンドの登録
先ほど作成したコマンドを、 invoke_handler
で登録。
diff --git a/tauri/tauri-app-event/src-tauri/src/main.rs b/tauri/tauri-app-event/src-tauri/src/main.rs
index e994ea4..2dd091a 100644--- a/tauri/tauri-app-event/src-tauri/src/main.rs
+++ b/tauri/tauri-app-event/src-tauri/src/main.rs
@@ -3,8 +3,13 @@
windows_subsystem = "windows"
)]
+mod command;
+
fn main() {
tauri::Builder::default()+ // setup 中ではできない初期化処理を実行するコマンドを登録
+ // setup 中に spawn ができないので、それを行う
+ .invoke_handler(tauri::generate_handler![command::post_setup_process_for_backend])
.run(tauri::generate_context!())
.expect("error while running tauri application"); }
レンダープロセス側にイベント受信処理を追加
window.__TAURI__.event.listen
関数を使って、イベント受信時に実行する関数を設定する。
diff --git a/tauri/tauri-app-event/dist/index.html b/tauri/tauri-app-event/dist/index.html
index 8da7e6c..507bb5e 100644--- a/tauri/tauri-app-event/dist/index.html
+++ b/tauri/tauri-app-event/dist/index.html
@@ -10,11 +10,42 @@
}
body {- display: flex;
align-items: center;
justify-content: center;
}
</style>+ <script type="text/javascript">
+ document.addEventListener('DOMContentLoaded', function() {
+ const invoke = window.__TAURI__.invoke;
+ const listen = window.__TAURI__.event.listen;
+
+ async function init() {
+ // バックエンドの初期化処理呼び出し
+ await invoke('post_setup_process_for_backend', {});
+
+ // バックエンドが emit するイベントの listen
+ // イベント名: backendHello
+ // 受信データ: { message: "Hello, World from backend!!!" }(`event.payload` に格納されている)
+ const unlistenBackendHello = await listen('backendHello', event => {
+ console.log(event);
+ const p = document.createElement('p');
+ p.textContent = event.payload.message;
+ document.body.append(p);
+ });
+
+ // 5 秒後に listen を止める
+ setTimeout(() => {
+ console.log("timeout.");
+ unlistenBackendHello();
+ const p = document.createElement('p');
+ p.textContent = 'stop event listen.';
+ document.body.append(p);
+ }, 5000);
+ }
+
+ init();
+
+ });
+ </script>
<body>
<h1>tauri-app-event</h1> </body>
ここまで追加したのち、 npx tauri dev
コマンドで実行すると、以下の挙動が確認できる。
- Rust 側で、 10 秒間、 1 秒ごとにイベントを発行
- JS 側で、起動から 5 秒間イベントを listen し、それ以後無視する
コメントが無いなど、多少差分があるが、前述の方針で実装したものを以下に格納しているので、必要に応じて確認してください。
0 件のコメント:
コメントを投稿