主题
IPC 通信
Tauri 的 IPC 是异步消息传递。前端和核心进程交换可序列化的请求与响应。
主要原语:
Command:前端调用 Rust 函数,适合请求响应。Event:单向通知,适合生命周期和状态变化。Channel:适合分块流式数据。
Command
Rust 侧用 #[tauri::command] 注册函数:
rust
#[tauri::command]
fn app_version() -> String {
env!("CARGO_PKG_VERSION").into()
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![app_version])
.run(tauri::generate_context!())
.expect("error while running tauri application")
}前端调用:
ts
import { invoke } from '@tauri-apps/api/core'
const version = await invoke<string>('app_version')参数以 JSON 对象传递。Rust 参数名是 snake_case 时,前端使用 camelCase:
rust
#[tauri::command]
fn settings_set(key: String, value: String) -> Result<(), String> {
if key.is_empty() || value.is_empty() {
return Err("Invalid settings".into())
}
Ok(())
}ts
await invoke('settings_set', { key: 'theme', value: 'dark' })返回值需要实现 serde::Serialize。可能失败时返回 Result,前端 invoke 会变成 Promise reject。
同步 Command 默认跑在主线程。耗时逻辑应写成 async,由运行时调度到独立任务。
多个 Command 必须在同一次 generate_handler! 中注册,后一次 invoke_handler 会覆盖前一次。
Event
Event 没有返回值,也不做类型约束,只传 JSON。
前端发送:
ts
import { emit, listen } from '@tauri-apps/api/event'
await emit('download:progress', { percent: 50 })
const unlisten = await listen<{ percent: number }>('download:progress', (event) => {
console.log(event.payload.percent)
})
unlisten()Rust 侧也可以 listen / emit。组件卸载时要取消监听,避免重复回调。
高吞吐、有序的流式数据优先用 Channel,不要用 Event 模拟传输通道。
命名
推荐使用命名空间:
bash
app_version
settings_get
settings_set
file_open
download:progressCommand 名称来自 Rust 函数名,保持具体。避免 message、event、invoke 这类万能通道。
封装建议
- 前端通过
@tauri-apps/api调用,不直接依赖window.__TAURI__。 - 一个业务能力对应一个明确 Command。
- handler 内做参数校验和服务调用,复杂逻辑放到独立 Rust 模块。
- 前端拿到的是普通数据,不是 Rust 对象引用。
- 自定义 Command 默认对所有窗口开放;需要收紧时在
capabilities和AppManifest::commands中声明允许列表。
