You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Rocket请求中触发Tauri窗口事件?

解决方案

核心问题是Rocket路由函数无法直接访问外部的Tauri窗口句柄,需要通过线程安全的共享状态让路由函数获取窗口实例,具体步骤如下:

1. 导入必要依赖

确保引入线程安全相关的包:

use std::sync::{Arc, Mutex};
use rocket::State;

2. 包装窗口句柄并注入Rocket状态

将Tauri窗口用Arc<Mutex<>>包装,确保异步环境下线程安全访问,再通过Rocket的manage方法注入到应用状态中:

#[rocket::main]
async fn main() {
    tauri::Builder::default()
        .setup(|app| {
            // 用Arc<Mutex>包装窗口句柄,实现线程安全共享
            let window = Arc::new(Mutex::new(app.get_window("main").unwrap()));

            // 定义路由函数,通过State guard获取窗口实例
            #[get("/")]
            fn index(window: &State<Arc<Mutex<tauri::Window>>>) {
                // 锁定窗口并发送事件
                if let Ok(mut win) = window.lock() {
                    win.emit("from-rust", "收到Web控制面板请求").expect("发送事件失败");
                }
            }
            
            // 启动Rocket时注入窗口状态
            tauri::async_runtime::spawn(async move {
                let _rocket = rocket::build()
                    .manage(window) // 将窗口实例加入Rocket状态
                    .mount("/", routes![index])
                    .launch().await;
            });
            
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("运行Tauri应用失败");
}

3. 关键说明

  • Arc<Mutex<Window>>:Arc允许多线程共享所有权,Mutex保证同一时间只有一个线程访问窗口,避免并发安全问题。
  • Rocket的State guard:路由函数通过&State<T>参数可以安全获取注入的全局状态,这是Rocket提供的状态管理机制。
  • 错误处理:使用if let Ok(mut win)处理lock()可能返回的PoisonError(比如窗口已被销毁),避免程序崩溃。

扩展思路

  • 可以针对不同动作定义多个路由(比如/show-dashboard、/refresh-data),在对应的路由函数中发送不同的事件。
  • 如果需要传递参数,可在路由中添加路径参数或查询参数,比如#[get("/action?<cmd>")],然后将cmd作为事件数据发送给窗口。

内容的提问来源于stack exchange,提问作者CUGreen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 08:45:27