フロントエンドからのイベントを Rust で受ける

Recipe ID: rust-011

通常、フロントエンドから Rust を呼び出すには「コマンド (invoke)」を使いますが、戻り値を待つ必要がなかったり、一方的な通知を送りたいだけの場合は「イベント (emit)」を使うこともできます。

1. フロントエンドから送信 (emit)

JavaScript/TypeScript 側から emit 関数を呼び出します。

import { emit } from '@tauri-apps/api/event';

async function sendLog() {
  const logData = {
    level: 'info',
    message: 'ユーザーがボタンをクリックしました'
  };

  // 'front-to-back' というイベント名で送信
  await emit('front-to-back', logData);
}

2. Rust 側で受信 (listen)

Rust 側では、アプリの初期化時 (lib.rssetup フック内) や、ウィンドウ作成時などに listen メソッドで待ち受けを設定します。

// src-tauri/src/lib.rs
use tauri::{Listener, Manager}; // Manager トレイトが必要です

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .setup(|app| {
            // アプリ全体でイベントをリッスンする
            // イベント名はフロントエンド側と一致させる必要があります
            app.listen("front-to-back", |event| {
                // event.payload() は生文字列(JSON形式のString)として受け取ります
                println!("イベントを受信しました: {:?}", event.payload());
                
                // 必要ならここで serde_json などを使ってパースします
                if let Ok(msg) = serde_json::from_str::<serde_json::Value>(event.payload()) {
                     println!("メッセージ内容: {}", msg["message"]);
                }
            });
            
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

コマンドとの使い分け

  • コマンド (invoke): 「リクエスト&レスポンス」型。結果を知りたい場合や、処理の完了を待ちたい場合に最適です(推奨)。
  • イベント (emit): 「投げっぱなし」型。ログ送信や、結果を待たずに次の処理に進みたい場合に便利です。

基本的には invoke を使い、特別な理由がある場合のみイベントを使う設計をおすすめします。